feat: 卫生供应新增任务中心(4类终端任务Tab) + 订餐终端净菜包货柜 + 净菜加工包装规格 + 包装标签完成时间/状态列

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-08-20 18:16:37 +08:00
co-authored by Claude Opus 4.7
parent a155c0d122
commit 3bdc47629c
16 changed files with 637 additions and 26 deletions
+1 -1
View File
@@ -7,7 +7,7 @@
<value>
<TabSessionState>
<option name="provider" value="claude" />
<option name="sessionId" value="74d0830a-01f8-44b3-afd4-267a8ccb514e" />
<option name="sessionId" value="dae386aa-002c-43d2-97b6-f23b42b368d5" />
<option name="cwd" value="$PROJECT_DIR$" />
<option name="model" value="claude-opus-4-7[1m]" />
<option name="permissionMode" value="bypassPermissions" />
+1
View File
@@ -293,6 +293,7 @@ const SITE_MAP = [
{ file:'sup-clean-external.html', label:'净菜外售' },
{ file:'sup-biz-analysis.html', label:'加工经营分析' },
{ file:'sup-process-analysis.html', label:'加工分析' },
{ file:'sup-task-center.html', label:'任务中心' },
{ file:'din-user-mgmt.html', label:'用户管理' },
{ file:'din-user-recharge.html', label:'批量充值' },
{ file:'din-dish-all.html', label:'菜品总库' },
+33 -8
View File
@@ -672,6 +672,7 @@ var OV_TABS=[
{key:'smart',name:'智能货柜',icon:'🗄️'},
{key:'raw',name:'毛菜货柜',icon:'🥬'},
{key:'clean',name:'净菜货柜',icon:'🧺'},
{key:'pack',name:'净菜包货柜',icon:'📦'},
{key:'meter-e',name:'智能电表',icon:'⚡'},
{key:'meter-w',name:'智能水表',icon:'💧'},
{key:'meter-g',name:'智能气表',icon:'🔥'}
@@ -727,6 +728,7 @@ function renderOvTabBody(key){
if(key==='smart')return renderSmartCabinet();
if(key==='plate')return renderPlateCabinet();
if(key==='clean')return renderStockCabinet('clean');
if(key==='pack')return renderStockCabinet('pack');
if(key==='raw')return renderStockCabinet('raw');
if(key==='meter-e')return renderEnergyTab('elec');
if(key==='meter-w')return renderEnergyTab('water');
@@ -1038,7 +1040,7 @@ function confirmPlateUnbind(idx){
/* ===== 净菜货柜 / 毛菜货柜(参考 sup-warehouse.html 智能货柜功能属性,重新布局) ===== */
/* 格口状态:occupied 储物中 / idle 空闲 / offline 离线 */
var STOCK_CABINETS={
clean:{name:'3号净菜柜',code:'CAB-NC-001',type:'净菜柜',typeTag:'tag-blue',status:'在线 · 冷藏 2.4℃',
clean:{name:'3号净菜柜',code:'CAB-NC-001',type:'净菜柜',typeTag:'tag-blue',itemLabel:'净菜',status:'在线 · 冷藏 2.4℃',
slots:[
{id:'NC3-01',status:'occupied',itemName:'净土豆丝',qty:10.2,op:'张厨师',inTime:'2026-08-18 09:15',inOrder:'IN-20260818-001',
history:[{time:'2026-08-18 14:20',type:'取出',before:11.0,after:10.2,op:'王厨师',order:'IN-20260818-001',remark:'做土豆丝炒肉'},{time:'2026-08-18 11:30',type:'取出',before:11.8,after:11.0,op:'李主管',order:'IN-20260818-001',remark:'做宫保鸡丁'},{time:'2026-08-18 09:15',type:'存入',before:0,after:12.5,op:'张厨师',order:'IN-20260818-001',remark:'首次入柜'}]},
@@ -1052,7 +1054,7 @@ var STOCK_CABINETS={
history:[{time:'2026-08-18 11:10',type:'取出',before:18.7,after:18.0,op:'王厨师',order:'IN-20260818-006',remark:'做白菜炖豆腐'},{time:'2026-08-18 08:50',type:'存入',before:0,after:23.0,op:'王厨师',order:'IN-20260818-006',remark:'首次入柜'}]},
{id:'NC3-06',status:'idle'},{id:'NC3-07',status:'idle'},{id:'NC3-08',status:'idle'},{id:'NC3-09',status:'idle'},{id:'NC3-10',status:'idle'}
]},
raw:{name:'8号毛菜柜',code:'CAB-RW-008',type:'毛菜柜',typeTag:'tag-green',status:'在线 · 常温通风',
raw:{name:'8号毛菜柜',code:'CAB-RW-008',type:'毛菜柜',typeTag:'tag-green',itemLabel:'毛菜',status:'在线 · 常温通风',
slots:[
{id:'RW8-A1',status:'occupied',itemName:'菠菜',qty:225.0,op:'张仓管',inTime:'2026-08-15 10:30',inOrder:'IN-20260815-001',
history:[{time:'2026-08-17 09:00',type:'取出',before:261.0,after:225.0,op:'李仓管',order:'IN-20260815-001',remark:'净菜加工领用'},{time:'2026-08-15 10:30',type:'存入',before:0,after:286.0,op:'张仓管',order:'IN-20260815-001',remark:'毛菜入库'}]},
@@ -1067,9 +1069,31 @@ var STOCK_CABINETS={
{id:'RW8-C1',status:'occupied',itemName:'芹菜',qty:12.0,op:'张仓管',inTime:'2026-08-14 16:00',inOrder:'IN-20260814-003',
history:[{time:'2026-08-17 08:50',type:'取出',before:15.0,after:12.0,op:'王仓管',order:'IN-20260814-003',remark:'凉拌芹菜领用'},{time:'2026-08-14 16:00',type:'存入',before:0,after:15.0,op:'张仓管',order:'IN-20260814-003',remark:'毛菜入库'}]},
{id:'RW8-C2',status:'idle'},{id:'RW8-C3',status:'idle'}
]},
pack:{name:'5号净菜包柜',code:'CAB-NCP-005',type:'净菜包柜',typeTag:'tag-orange',itemLabel:'净菜包',status:'在线 · 冷藏 2.8℃',
slots:[
{id:'NCP5-01',status:'occupied',itemName:'宫保鸡丁净菜包',qty:45,unit:'袋',op:'张厨师',inTime:'2026-08-18 09:15',inOrder:'IN-20260818-031',
history:[{time:'2026-08-18 14:20',type:'取出',before:50,after:45,op:'王厨师',order:'OUT-20260818-031',remark:'午餐配餐领用'},{time:'2026-08-18 09:15',type:'存入',before:0,after:50,op:'张厨师',order:'IN-20260818-031',remark:'包装完入库'}]},
{id:'NCP5-02',status:'occupied',itemName:'鱼香肉丝净菜包',qty:32,unit:'袋',op:'张厨师',inTime:'2026-08-18 09:20',inOrder:'IN-20260818-032',
history:[{time:'2026-08-18 15:40',type:'取出',before:36,after:32,op:'李主管',order:'OUT-20260818-032',remark:'晚餐备餐领用'},{time:'2026-08-18 09:20',type:'存入',before:0,after:36,op:'张厨师',order:'IN-20260818-032',remark:'包装完入库'}]},
{id:'NCP5-03',status:'occupied',itemName:'麻婆豆腐净菜包',qty:28,unit:'袋',op:'王厨师',inTime:'2026-08-18 09:30',inOrder:'IN-20260818-033',
history:[{time:'2026-08-18 16:10',type:'取出',before:30,after:28,op:'张厨师',order:'OUT-20260818-033',remark:'配餐领用'},{time:'2026-08-18 09:30',type:'存入',before:0,after:30,op:'王厨师',order:'IN-20260818-033',remark:'包装完入库'}]},
{id:'NCP5-04',status:'occupied',itemName:'青椒肉丝净菜包',qty:3,unit:'件',op:'张厨师',inTime:'2026-08-17 16:00',inOrder:'IN-20260817-012',
history:[{time:'2026-08-18 11:20',type:'取出',before:4,after:3,op:'李主管',order:'OUT-20260818-012',remark:'整件领用(1件=20袋)'},{time:'2026-08-17 16:00',type:'存入',before:0,after:4,op:'张厨师',order:'IN-20260817-012',remark:'包装完入库'}]},
{id:'NCP5-05',status:'occupied',itemName:'番茄炒蛋净菜包',qty:60,unit:'袋',op:'王厨师',inTime:'2026-08-18 08:50',inOrder:'IN-20260818-026',
history:[{time:'2026-08-18 12:30',type:'取出',before:68,after:60,op:'张厨师',order:'OUT-20260818-026',remark:'午餐配餐领用'},{time:'2026-08-18 08:50',type:'存入',before:0,after:68,op:'王厨师',order:'IN-20260818-026',remark:'包装完入库'}]},
{id:'NCP5-06',status:'occupied',itemName:'土豆炖牛肉净菜包',qty:2,unit:'箱',op:'张厨师',inTime:'2026-08-17 15:30',inOrder:'IN-20260817-018',
history:[{time:'2026-08-18 10:40',type:'取出',before:3,after:2,op:'李主管',order:'OUT-20260818-018',remark:'整箱领用(1箱=10袋)'},{time:'2026-08-17 15:30',type:'存入',before:0,after:3,op:'张厨师',order:'IN-20260817-018',remark:'包装完入库'}]},
{id:'NCP5-07',status:'idle'},{id:'NCP5-08',status:'idle'},{id:'NCP5-09',status:'idle'},{id:'NCP5-10',status:'idle'}
]}
};
/* 数量格式化:重量(kg)保留1位小数,包装单位(袋/件/箱等)显示整数 */
function fmtQty(n,unit){
if(!unit||unit==='kg')return Number(n).toFixed(1);
return String(Math.round(Number(n)));
}
function renderStockCabinet(kind){
const cab=STOCK_CABINETS[kind];
const occupied=cab.slots.filter(s=>s.status==='occupied').length;
@@ -1079,7 +1103,7 @@ function renderStockCabinet(kind){
}
const cls=s.status==='offline'?'ov-slot offline':'ov-slot occupied';
const badge=s.status==='offline'?'<div class="ov-slot__badge gray"></div>':'<div class="ov-slot__badge green"></div>';
const qtyHtml=s.status==='offline'?'<div class="ov-slot__expire" style="color:var(--text-placeholder)">离线</div>':`<div class="ov-slot__remain">${s.qty}kg</div><div class="ov-slot__expire">入库 ${s.inTime.slice(5,10)}</div>`;
const qtyHtml=s.status==='offline'?'<div class="ov-slot__expire" style="color:var(--text-placeholder)">离线</div>':`<div class="ov-slot__remain">${fmtQty(s.qty,s.unit)}${s.unit||'kg'}</div><div class="ov-slot__expire">入库 ${s.inTime.slice(5,10)}</div>`;
return `<div class="${cls}" onclick="showStockSlot('${kind}',${i})">
${badge}
<div class="ov-slot__id">${s.id}</div>
@@ -1105,6 +1129,7 @@ function renderStockCabinet(kind){
function showStockSlot(kind,idx){
const cab=STOCK_CABINETS[kind];
const s=cab.slots[idx];
const unit=s.unit||'kg';
if(s.status==='idle'){
showOvToast('该格口为空闲状态,暂无存放信息');
return;
@@ -1114,8 +1139,8 @@ function showStockSlot(kind,idx){
<div class="plate-detail__field"><span class="plate-detail__label">所属柜</span><span class="plate-detail__value">${cab.name}${cab.code}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">格口</span><span class="plate-detail__value">${s.id}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">格口状态</span><span class="plate-detail__value">${statusTag}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">存放物品</span><span class="plate-detail__value">${s.itemName}<span class="tag ${cab.typeTag}" style="margin-left:6px">${cab.type==='净菜柜'?'净菜':'毛菜'}</span></span></div>
<div class="plate-detail__field"><span class="plate-detail__label">当前数量(kg)</span><span class="plate-detail__value">${s.qty.toFixed(1)}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">存放物品</span><span class="plate-detail__value">${s.itemName}<span class="tag ${cab.typeTag}" style="margin-left:6px">${cab.itemLabel}</span></span></div>
<div class="plate-detail__field"><span class="plate-detail__label">当前数量(${unit})</span><span class="plate-detail__value">${fmtQty(s.qty,s.unit)}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">操作人</span><span class="plate-detail__value">${s.op}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">入库时间</span><span class="plate-detail__value">${s.inTime}</span></div>
<div class="plate-detail__field"><span class="plate-detail__label">关联入库单</span><span class="plate-detail__value" style="color:var(--primary)">${s.inOrder}</span></div>
@@ -1123,12 +1148,12 @@ function showStockSlot(kind,idx){
const rows=(s.history||[]).slice().sort((a,b)=>b.time.localeCompare(a.time));
if(rows.length){
html+=`<div class="plate-detail__section"><div class="plate-detail__section-title">存取历史</div>
<table class="slot-his-table"><thead><tr><th>操作时间</th><th>操作类型</th><th>操作前(kg)</th><th>操作后(kg)</th><th>余量变化</th><th>操作人</th><th>关联单号</th><th>备注</th></tr></thead><tbody>
<table class="slot-his-table"><thead><tr><th>操作时间</th><th>操作类型</th><th>操作前(${unit})</th><th>操作后(${unit})</th><th>余量变化</th><th>操作人</th><th>关联单号</th><th>备注</th></tr></thead><tbody>
${rows.map(r=>{
const isPos=r.type==='存入';
const delta=Math.abs(r.after-r.before).toFixed(1);
const delta=fmtQty(Math.abs(r.after-r.before),unit);
const typeHtml=isPos?'<span class="tag tag-blue">存入</span>':'<span class="tag tag-orange">取出</span>';
return `<tr><td>${r.time}</td><td>${typeHtml}</td><td>${r.before.toFixed(1)}</td><td>${r.after.toFixed(1)}</td><td><span class="slot-his-delta ${isPos?'pos':'neg'}">${isPos?'+':'-'}${delta} ${isPos?'↑':'↓'}</span></td><td>${r.op}</td><td><a class="link">${r.order}</a></td><td>${r.remark||'—'}</td></tr>`;
return `<tr><td>${r.time}</td><td>${typeHtml}</td><td>${fmtQty(r.before,unit)}</td><td>${fmtQty(r.after,unit)}</td><td><span class="slot-his-delta ${isPos?'pos':'neg'}">${isPos?'+':'-'}${delta} ${isPos?'↑':'↓'}</span></td><td>${r.op}</td><td><a class="link">${r.order}</a></td><td>${r.remark||'—'}</td></tr>`;
}).join('')}
</tbody></table></div>`;
}
+16
View File
@@ -1,5 +1,21 @@
# 营养用餐管理端 CHANGELOG
## [2026-08-20] feat: 订餐终端净菜包货柜 + 净菜加工包装规格 + 包装标签状态列
- `din-terminal.html` 订餐终端设备概览:货柜 Tab 新增「净菜包货柜」,货柜数据模型新增 `itemLabel`/`unit` 字段,支持按包装单位(袋/件/箱)展示,非 kg 单位数量取整数
- `prod-clean-order.html` 净菜加工订单:食谱餐品明细表新增「包装规格」列(克数输入 + 包装单位下拉),提交订单时优先使用明细表编辑后的规格
- `sup-pkg-label.html` 包装标签:净菜/配餐包装两个列表新增「完成时间」「状态」列(已入柜/已发货/未知)
## [2026-08-20] feat: 卫生供应新增任务中心(`sup-task-center.html`)
- 卫生供应侧边栏新增「任务中心」菜单项(位于「数据分析」之后、侧边栏最末尾)
- `sup-task-center.html` 任务中心:4 个 Tab 分设备查看终端任务
- 毛菜加工任务(毛菜加工秤)、净菜加工任务(净菜加工秤)、净菜组配任务(净菜组配秤)、净菜包装任务(净菜包装贴标秤)
- 统一列表字段:任务编号 / 关联单号 / 任务内容摘要 / 任务状态 / 执行人 / 生成时间 / 截止时间 / 完成时间 / 操作
- 任务状态保留各设备原始语义(待处理/待加工/待组配/待包装/进行中/待发货/已完成/已发货),配色统一橙=未完成、蓝=进行中、绿=已完成
- 支持筛选(任务编号/状态/执行人/生成时间范围)、导出列表数据/查看导出任务(占位)、查看详情(右侧抽屉展示任务信息+明细),不支持新增/编辑
- 同步更新 10 个卫生供应页面侧边栏 + `index.html` SITE_MAP
## [2026-08-20] feat: 报表中心两页面补齐 — 场所经营分析 + 场所目标考核(`din-place-biz-analysis.html` / `din-place-goal.html`)
- 原「场所经营分析」「场所目标考核」为占位页,本次补齐为完整报表页
+31 -4
View File
@@ -368,7 +368,7 @@ tr.detail-row td.td-actions{background:#FAFBFC;box-shadow:-4px 0 8px rgba(0,0,0,
<div class="drawer-section__title">餐品明细(重复餐品已自动合并,请逐道确认是否需要内配调料)</div>
<div style="overflow-x:auto;">
<table class="inline-builder-table" id="dishSeasoningTable" style="margin-bottom:0;">
<thead><tr><th style="width:50%;">菜品名称</th><th>内配调料</th></tr></thead>
<thead><tr><th style="width:34%;">菜品名称</th><th>包装规格</th><th>内配调料</th></tr></thead>
<tbody id="dishSeasoningBody"></tbody>
</table>
</div>
@@ -1357,6 +1357,8 @@ function onRecipeDateChange(){
/* ========== 餐品调料配置表(食谱快速创建专用) ========== */
/* recipeSeasoningMap: { 菜名: true|false },跨餐次重复菜品自动合并,状态在重渲时保留 */
var recipeSeasoningMap={};
/* recipeSpecMap: { 菜名: {baseGram, portion, unit} },餐品明细表包装规格编辑值,重渲时保留 */
var recipeSpecMap={};
function renderDishSeasoningTable(){
var section=document.getElementById('dishSeasoningSection');
var tbody=document.getElementById('dishSeasoningBody');
@@ -1386,7 +1388,18 @@ function renderDishSeasoningTable(){
/* 未配置过的菜品默认 false(不需要);已配置的保留 */
if(typeof recipeSeasoningMap[name]!=='boolean')recipeSeasoningMap[name]=false;
var ns=recipeSeasoningMap[name]===true;
/* 未编辑过包装规格的菜品,用兜底规格初始化 */
if(!recipeSpecMap[name]){
var sp=getDishSpecForRecipe(name);
recipeSpecMap[name]={baseGram:sp.baseGram,unit:sp.unit||'袋'};
}
var spec=recipeSpecMap[name];
html+='<tr><td style="font-weight:500;">'+name+'</td>';
/* 包装规格:左 input 克数 + 右 select 包装单位 */
html+='<td><div class="spec-input-group">'
+'<input inputmode="numeric" placeholder="克数" value="'+(spec.baseGram||'')+'" oninput="this.value=this.value.replace(/[^\\d]/g,\'\');updateRecipeSpecGram(\''+name.replace(/'/g,'\\\'')+'\',this.value)">'
+'<select onchange="updateRecipeSpecUnit(\''+name.replace(/'/g,'\\\'')+'\',this.value)">'+buildUnitOptions(spec.unit)+'</select>'
+'</div></td>';
html+='<td><div class="seasoning-radio-group">';
html+='<label><input type="radio" name="rs-'+encodeURIComponent(name)+'" '+(ns?'checked':'')+' onchange="updateRecipeSeasoning(\''+name.replace(/'/g,'\\\'')+'\',true)"> 是</label>';
html+='<label><input type="radio" name="rs-'+encodeURIComponent(name)+'" '+(!ns?'checked':'')+' onchange="updateRecipeSeasoning(\''+name.replace(/'/g,'\\\'')+'\',false)"> 否</label>';
@@ -1397,6 +1410,16 @@ function renderDishSeasoningTable(){
function updateRecipeSeasoning(name,val){
recipeSeasoningMap[name]=!!val;
}
/* 更新食谱餐品包装规格克数 */
function updateRecipeSpecGram(name,val){
if(!recipeSpecMap[name])recipeSpecMap[name]={baseGram:0,unit:'袋'};
recipeSpecMap[name].baseGram=parseInt(val,10)||0;
}
/* 更新食谱餐品包装规格单位 */
function updateRecipeSpecUnit(name,val){
if(!recipeSpecMap[name])recipeSpecMap[name]={baseGram:0,unit:'袋'};
recipeSpecMap[name].unit=val;
}
/* 校验所选餐次是否都已填写就餐人数,并返回缺失餐次名 */
function validateMealDinerCounts(checkedMealIndices){
@@ -1440,13 +1463,16 @@ function submitRecipeOrder(){
for(var name in dishMap){
var item=dishMap[name];
var sp=item.spec;
var baseGram=sp.baseGram;
/* 优先使用餐品明细表中编辑过的包装规格,未编辑则回退默认规格 */
var edited=recipeSpecMap[name];
var baseGram=edited?edited.baseGram:sp.baseGram;
var unit=edited?(edited.unit||sp.unit):sp.unit;
var servings=item.dinerCount;
newLines.push({
id:'L'+(Date.now()+di),
ncType:'cp',foodName:name,
spec:baseGram+'g/'+(sp.portion||sp.unit),
portion:sp.portion,baseGram:baseGram,unit:sp.unit,
spec:baseGram+'g/'+unit,
portion:sp.portion,baseGram:baseGram,unit:unit,
qty:servings,
weight:parseFloat((baseGram*servings/1000).toFixed(2)),
status:'生成中',
@@ -1479,6 +1505,7 @@ function sanitizeIntegerInput(el){el.value=el.value.replace(/[^\d]/g,'');}
document.getElementById('recipeDeliveryTime').value=getDefaultDeliveryTime();
document.getElementById('dailyMenuSection').style.display='none';
recipeSeasoningMap={};
recipeSpecMap={};
onRecipeDateChange();
}
document.getElementById(id).classList.add('show');
@@ -122,6 +122,7 @@ tr:hover td{background:#FAFAFA;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容 -->
@@ -178,6 +178,7 @@ textarea.form-control{height:auto;padding:8px 12px;resize:vertical;min-height:60
<a href="sup-pkg-label.html" class="sidebar-item"><span class="mi">🏷️</span>净菜包装</a>
<a href="sup-clean-internal.html" class="sidebar-item"><span class="mi">🏠</span>净菜内供</a>
<a href="sup-clean-external.html" class="sidebar-item active"><span class="mi">🚛</span>净菜外售</a>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<script>
@@ -229,6 +229,7 @@ tr.detail-row td.td-actions{background:#FAFBFC;box-shadow:-4px 0 8px rgba(0,0,0,
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<div class="main">
<div class="filter-bar">
@@ -178,6 +178,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容区 -->
+1
View File
@@ -186,6 +186,7 @@ tbody td.td-actions{white-space:nowrap;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容区 -->
+1
View File
@@ -190,6 +190,7 @@ tbody td.td-actions{white-space:nowrap;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容区 -->
+1
View File
@@ -185,6 +185,7 @@ tbody tr:hover{background:#F8FBFF;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容区 -->
+14 -13
View File
@@ -176,6 +176,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容 -->
@@ -227,15 +228,15 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<div class="table-card__content">
<table>
<thead><tr>
<th>包装批次号</th><th>溯源码</th><th>净菜名称</th><th>包装方式</th><th>包装规格</th><th>包装份数</th><th>包装日期</th><th>保质期至</th><th>存放温度(℃)</th><th>包装人</th><th>操作类型</th><th>终端设备</th><th>操作</th>
<th>包装批次号</th><th>溯源码</th><th>净菜名称</th><th>包装方式</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>BATCH-NC-20260415-01</td><td>NC-PROC-BOCA-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">真空袋</span></td><td>500g/袋</td><td>20</td><td>2026-04-15</td><td>2026-04-17</td><td>4.1</td><td>李包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-01</td><td>NC-PROC-BOCA-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">真空袋</span></td><td>500g/袋</td><td>20</td><td>2026-04-15</td><td>2026-04-17</td><td>4.1</td><td>李包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-02</td><td>NC-PROC-HLUB-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">保鲜盒</span></td><td>1000g/箱</td><td>15</td><td>2026-04-15</td><td>2026-04-18</td><td>4.2</td><td>王包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-02</td><td>NC-PROC-HLUB-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">保鲜盒</span></td><td>1000g/箱</td><td>15</td><td>2026-04-15</td><td>2026-04-18</td><td>4.2</td><td>王包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-03</td><td>NC-PROC-XGUO-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">散装托盘</span></td><td>2000g/箱</td><td>8</td><td>2026-04-15</td><td>2026-04-17</td><td>4.0</td><td>张包装</td><td><span class="tag tag-green">人工录入</span></td><td></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-04</td><td>NC-PROC-LAJP-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">真空袋</span></td><td>1000g/袋</td><td>12</td><td>2026-04-15</td><td>2026-04-17</td><td>4.3</td><td>李包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-2号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T02</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-01</td><td>NC-PROC-BOCA-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">真空袋</span></td><td>500g/袋</td><td>20</td><td>2026-04-15</td><td>2026-04-17</td><td>4.1</td><td>李包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td>2026-04-15 11:45</td><td><span class="tag tag-green">已入柜</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-01</td><td>NC-PROC-BOCA-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">真空袋</span></td><td>500g/袋</td><td>20</td><td>2026-04-15</td><td>2026-04-17</td><td>4.1</td><td>李包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td>2026-04-15 11:45</td><td><span class="tag tag-green">已入柜</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-02</td><td>NC-PROC-HLUB-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">保鲜盒</span></td><td>1000g/箱</td><td>15</td><td>2026-04-15</td><td>2026-04-18</td><td>4.2</td><td>王包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td>2026-04-15 12:10</td><td><span class="tag tag-blue">已发货</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-02</td><td>NC-PROC-HLUB-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">保鲜盒</span></td><td>1000g/箱</td><td>15</td><td>2026-04-15</td><td>2026-04-18</td><td>4.2</td><td>王包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T01</div></td><td>2026-04-15 12:10</td><td><span class="tag tag-blue">已发货</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-03</td><td>NC-PROC-XGUO-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">散装托盘</span></td><td>2000g/箱</td><td>8</td><td>2026-04-15</td><td>2026-04-17</td><td>4.0</td><td>张包装</td><td><span class="tag tag-green">人工录入</span></td><td></td><td>2026-04-15 13:05</td><td><span class="tag tag-gray">未知</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-NC-20260415-04</td><td>NC-PROC-LAJP-20260415-01</td><td>土豆-土豆丝</td><td><span class="tag tag-gray">真空袋</span></td><td>1000g/袋</td><td>12</td><td>2026-04-15</td><td>2026-04-17</td><td>4.3</td><td>李包装</td><td><span class="tag tag-blue">设备自动</span></td><td><div>真空机-2号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T02</div></td><td>2026-04-15 13:20</td><td><span class="tag tag-blue">已发货</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
</tbody>
</table>
</div>
@@ -272,14 +273,14 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<div class="table-card__content">
<table>
<thead><tr>
<th>包装批次号</th><th>包装餐品</th><th>包装规格</th><th>包装方式</th><th>包装份数</th><th>包含食材</th><th>包装日期</th><th>保质期至</th><th>存放温度(℃)</th><th>包装人</th><th>操作类型</th><th>终端设备</th><th>操作</th>
<th>包装批次号</th><th>包装餐品</th><th>包装规格</th><th>包装方式</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>BATCH-DH-20260415-01</td><td>宫保鸡丁</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">冷鲜袋</span></td><td>10</td><td><span class="link" onclick="showIngredients(0)">3种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>3.8</td><td>赵配餐</td><td><span class="tag tag-blue">设备自动</span></td><td><div>封口机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T03</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-01</td><td>宫保鸡丁</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">冷鲜袋</span></td><td>10</td><td><span class="link" onclick="showIngredients(0)">3种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>3.8</td><td>赵配餐</td><td><span class="tag tag-blue">设备自动</span></td><td><div>封口机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T03</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-02</td><td>清蒸鱼</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">保鲜盒</span></td><td>8</td><td><span class="link" onclick="showIngredients(1)">2种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>3.5</td><td>陈配餐</td><td><span class="tag tag-green">人工录入</span></td><td></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-03</td><td>蒜蓉菠菜</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">冷鲜袋</span></td><td>12</td><td><span class="link" onclick="showIngredients(2)">2种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>4.0</td><td>陈配餐</td><td><span class="tag tag-green">人工录入</span></td><td></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-04</td><td>炒胡萝卜</td><td><span class="tag tag-blue">大份(800g</span></td><td><span class="tag tag-gray">保鲜盒</span></td><td>6</td><td><span class="link" onclick="showIngredients(3)">2种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>4.2</td><td>赵配餐</td><td><span class="tag tag-blue">设备自动</span></td><td><div>封口机-2号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T04</div></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-01</td><td>宫保鸡丁</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">冷鲜袋</span></td><td>10</td><td><span class="link" onclick="showIngredients(0)">3种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>3.8</td><td>赵配餐</td><td><span class="tag tag-blue">设备自动</span></td><td><div>封口机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T03</div></td><td>2026-04-15 11:30</td><td><span class="tag tag-blue">已发货</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-01</td><td>宫保鸡丁</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">冷鲜袋</span></td><td>10</td><td><span class="link" onclick="showIngredients(0)">3种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>3.8</td><td>赵配餐</td><td><span class="tag tag-blue">设备自动</span></td><td><div>封口机-1号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T03</div></td><td>2026-04-15 11:30</td><td><span class="tag tag-blue">已发货</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-02</td><td>清蒸鱼</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">保鲜盒</span></td><td>8</td><td><span class="link" onclick="showIngredients(1)">2种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>3.5</td><td>陈配餐</td><td><span class="tag tag-green">人工录入</span></td><td></td><td>2026-04-15 12:00</td><td><span class="tag tag-gray">未知</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-03</td><td>蒜蓉菠菜</td><td><span class="tag tag-green">标准份(500g</span></td><td><span class="tag tag-gray">冷鲜袋</span></td><td>12</td><td><span class="link" onclick="showIngredients(2)">2种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>4.0</td><td>陈配餐</td><td><span class="tag tag-green">人工录入</span></td><td></td><td>2026-04-15 12:25</td><td><span class="tag tag-green">已入柜</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
<tr><td>BATCH-DH-20260415-04</td><td>炒胡萝卜</td><td><span class="tag tag-blue">大份(800g</span></td><td><span class="tag tag-gray">保鲜盒</span></td><td>6</td><td><span class="link" onclick="showIngredients(3)">2种</span></td><td>2026-04-15</td><td>2026-04-17</td><td>4.2</td><td>赵配餐</td><td><span class="tag tag-blue">设备自动</span></td><td><div>封口机-2号</div><div style="font-size:var(--font-xs);color:var(--text-secondary);">PKG-T04</div></td><td>2026-04-15 13:15</td><td><span class="tag tag-blue">已发货</span></td><td class="td-actions"><span class="link">查看视频</span> <span class="link" onclick="openEditDh(this)">编辑</span> <span class="link" style="color:var(--danger)">删除</span></td></tr>
</tbody>
</table>
</div>
@@ -124,6 +124,7 @@ tr:hover td{background:#FAFAFA;}
<a href="sup-process-analysis.html" class="sidebar-item active"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容 -->
+532
View File
@@ -0,0 +1,532 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>营养管理 - 任务中心 | 健康CQ原型</title>
<style>
/* 设计令牌 */
*{box-sizing:border-box;margin:0;padding:0;}
body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei',sans-serif;background:#F5F7FA;color:#333;min-width:1280px;}
:root{
--primary:#1890FF;--primary-light:#E6F7FF;--success:#52C41A;--warning:#FAAD14;--danger:#FF4D4F;
--text-primary:#333;--text-secondary:#666;--text-placeholder:#999;--border:#E8E8E8;--background:#F5F7FA;
--font-xs:11px;--font-sm:13px;--font-base:15px;--font-lg:17px;--font-xl:20px;--font-xxl:24px;
--radius-sm:4px;--radius-md:8px;--radius-lg:12px;
--shadow-sm:0 1px 4px rgba(0,0,0,0.08);--shadow-md:0 4px 12px rgba(0,0,0,0.12);
}
/* 顶部导航 */
.top-bar{display:flex;align-items:center;height:56px;background:#001529;padding:0 24px;position:fixed;top:0;left:0;right:0;z-index:100;}
.top-bar__logo{display:flex;align-items:center;gap:8px;color:#fff;font-size:var(--font-lg);font-weight:600;white-space:nowrap;width:240px;flex-shrink:0;}
.top-bar__logo svg{width:28px;height:28px;}
.top-bar__nav{display:flex;align-items:center;gap:4px;flex:1;}
.top-bar__nav a{color:rgba(255,255,255,0.65);text-decoration:none;padding:6px 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);transition:all .2s;}
.top-bar__nav a:hover{color:#fff;background:rgba(255,255,255,0.08);}
.top-bar__nav a.active{color:#fff;background:var(--primary);}
.top-bar__right{display:flex;align-items:center;gap:16px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);}
.top-bar__right .btn-back{color:rgba(255,255,255,0.65);cursor:pointer;display:flex;align-items:center;gap:4px;text-decoration:none;}
.top-bar__right .btn-back:hover{color:#fff;}
.avatar{width:32px;height:32px;border-radius:50%;background:#1890FF;display:flex;align-items:center;justify-content:center;color:#fff;font-size:var(--font-sm);cursor:pointer;}
/* 侧边栏 */
.sidebar{position:fixed;top:56px;left:0;bottom:0;width:240px;background:#001529;overflow-y:auto;z-index:90;padding-top:8px;}
.sidebar-menu__title{color:rgba(255,255,255,0.35);font-size:var(--font-xs);padding:16px 24px 8px;text-transform:uppercase;letter-spacing:.5px;}
.sidebar-item{display:flex;align-items:center;gap:8px;padding:10px 24px;color:rgba(255,255,255,0.65);font-size:var(--font-sm);cursor:pointer;transition:all .15s;text-decoration:none;}
.sidebar-item:hover{color:#fff;background:rgba(255,255,255,0.06);}
.sidebar-item.active{color:#fff;background:var(--primary);}
.mi{display:inline-block;width:20px;text-align:center;filter:grayscale(1);opacity:0.65;margin-right:2px;}
.sidebar-item.active .mi{opacity:0.9;}
.sidebar-subgroup__header{display:flex;align-items:center;gap:6px;padding:10px 24px;font-size:var(--font-sm);color:rgba(255,255,255,0.45);cursor:pointer;user-select:none;}
.sidebar-subgroup__header .arrow{width:10px;height:10px;stroke:currentColor;transition:transform .2s;}
.sidebar-subgroup.open .sidebar-subgroup__header .arrow{transform:rotate(90deg);}
.sidebar-subgroup__body{display:none;padding-left:12px;}
.sidebar-subgroup.open .sidebar-subgroup__body{display:block;}
/* 主内容 */
.main{margin-left:240px;margin-top:56px;padding:24px;min-height:calc(100vh - 56px);}
/* Tab 切换栏 */
.tabs{display:flex;gap:8px;margin-bottom:16px;background:#fff;border-radius:var(--radius-md);padding:8px 12px;box-shadow:var(--shadow-sm);}
.tab{padding:8px 20px;border-radius:var(--radius-sm);font-size:var(--font-sm);font-weight:500;cursor:pointer;color:var(--text-secondary);transition:all .2s;border:1px solid transparent;}
.tab:hover{color:var(--primary);}
.tab.active{color:var(--primary);background:var(--primary-light);border-color:var(--primary);}
.tab__count{margin-left:6px;font-size:var(--font-xs);color:var(--text-placeholder);}
.tab.active .tab__count{color:var(--primary);}
/* 筛选栏 */
.filter-bar{background:#fff;border-radius:var(--radius-md);padding:20px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);display:flex;align-items:center;gap:16px;flex-wrap:wrap;}
.filter-item{display:flex;align-items:center;gap:8px;}
.filter-item label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
.filter-input{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;background:#fff;min-width:160px;}
.filter-input:focus{border-color:var(--primary);}
.filter-select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);color:var(--text-primary);outline:none;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6'%3E%3Cpath d='M0 0l5 6 5-6z' fill='%23999'/%3E%3C/svg%3E") no-repeat right 10px center;appearance:none;cursor:pointer;min-width:120px;}
/* 按钮 */
.btn{height:36px;padding:0 16px;border-radius:var(--radius-sm);font-size:var(--font-sm);cursor:pointer;border:none;transition:all .2s;display:inline-flex;align-items:center;gap:6px;}
.btn-primary{background:var(--primary);color:#fff;}.btn-primary:hover{background:#40a9ff;}
.btn-default{background:#fff;color:var(--text-primary);border:1px solid var(--border);}.btn-default:hover{color:var(--primary);border-color:var(--primary);}
/* 表格卡片 */
.table-card{background:#fff;border-radius:var(--radius-md);box-shadow:var(--shadow-sm);overflow:hidden;}
.table-card__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);}
.table-card__title{font-size:var(--font-base);font-weight:600;}
.table-card__content{overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;}
.table-card__content table{min-width:100%;white-space:nowrap;}
table{width:100%;border-collapse:collapse;}
thead th{background:#FAFAFA;padding:12px 16px;text-align:left;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
tbody td{padding:14px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);white-space:nowrap;}
/* 操作列固定右侧 */
thead th:last-child,tbody td.td-actions{position:sticky;right:0;background:#fff;box-shadow:-4px 0 8px rgba(0,0,0,0.04);z-index:2;white-space:nowrap;}
thead th:last-child{background:#FAFAFA;}
tbody tr:hover td.td-actions{background:#F8FBFF;}
thead th:last-child{background:#FAFAFA;}
tbody td:last-child{background:#fff;}
tbody tr:hover td:last-child{background:#F8FBFF;}
tbody tr:last-child td{border-bottom:none;}
tbody tr:hover{background:#F8FBFF;}
/* 标签 */
.tag{display:inline-flex;align-items:center;padding:2px 8px;border-radius:10px;font-size:var(--font-xs);}
.tag-blue{background:var(--primary-light);color:var(--primary);}
.tag-green{background:#F6FFED;color:var(--success);}
.tag-orange{background:#FFF7E6;color:var(--warning);}
.tag-red{background:#FFF1F0;color:var(--danger);}
.tag-gray{background:#F5F5F5;color:#999;}
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);text-decoration:none;}.link:hover{color:#40a9ff;}
/* 分页 */
.pagination{display:flex;align-items:center;justify-content:flex-end;padding:16px 24px;gap:8px;border-top:1px solid var(--border);}
.pagination span{font-size:var(--font-sm);color:var(--text-secondary);}
.page-btn{width:32px;height:32px;border:1px solid var(--border);border-radius:var(--radius-sm);background:#fff;cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;justify-content:center;transition:all .2s;}
.page-btn:hover,.page-btn.active{background:var(--primary);color:#fff;border-color:var(--primary);}
.action-bar{display:flex;align-items:center;gap:8px;margin-bottom:16px;}
/* 右侧抽屉 */
.drawer-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.45);z-index:1000;animation:modalFadeIn .2s ease;}
.drawer-overlay.closing{animation:modalFadeOut .2s ease forwards;}
@keyframes modalFadeIn{from{opacity:0}to{opacity:1}}
@keyframes modalFadeOut{from{opacity:1}to{opacity:0}}
.drawer{position:fixed;top:0;right:0;bottom:0;width:560px;max-width:90vw;background:#fff;box-shadow:-6px 0 24px rgba(0,0,0,.12);display:flex;flex-direction:column;z-index:1001;animation:drawerSlideIn .25s ease;}
.drawer-overlay.closing .drawer{animation:drawerSlideOut .2s ease forwards;}
@keyframes drawerSlideIn{from{transform:translateX(100%)}to{transform:translateX(0)}}
@keyframes drawerSlideOut{from{transform:translateX(0)}to{transform:translateX(100%)}}
.drawer__header{display:flex;align-items:center;justify-content:space-between;padding:16px 24px;border-bottom:1px solid var(--border);flex-shrink:0;}
.drawer__title{font-size:var(--font-lg);font-weight:600;color:var(--text-primary);}
.drawer__close{width:32px;height:32px;border:none;background:none;font-size:20px;cursor:pointer;border-radius:var(--radius-sm);color:var(--text-secondary);display:flex;align-items:center;justify-content:center;}
.drawer__close:hover{background:#f5f5f5;color:var(--text-primary);}
.drawer__body{padding:0 24px 24px;overflow-y:auto;flex:1;}
.drawer-section{margin-top:20px;}
.drawer-section__title{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);padding-bottom:8px;border-bottom:1px solid var(--border);margin-bottom:12px;display:flex;align-items:center;gap:6px;}
.drawer-section__title::before{content:'';display:inline-block;width:3px;height:14px;background:var(--primary);border-radius:2px;}
.drawer-fields{display:grid;grid-template-columns:1fr 1fr;gap:12px 24px;}
.drawer-field{display:flex;flex-direction:column;gap:2px;}
.drawer-field__label{font-size:var(--font-xs);color:var(--text-placeholder);}
.drawer-field__value{font-size:var(--font-sm);color:var(--text-primary);font-weight:500;min-height:22px;}
/* 明细表 */
.detail-table{width:100%;border-collapse:collapse;}
.detail-table th{background:#FAFAFA;padding:8px 12px;text-align:left;font-size:var(--font-xs);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
.detail-table td{padding:10px 12px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);}
.detail-table tr:last-child td{border-bottom:none;}
/* Toast */
.toast{position:fixed;top:80px;left:50%;transform:translateX(-50%) translateY(-20px);background:rgba(0,0,0,0.8);color:#fff;padding:12px 28px;border-radius:8px;font-size:13px;z-index:1200;opacity:0;visibility:hidden;transition:opacity .3s,transform .3s,visibility .3s;white-space:nowrap;pointer-events:none;}
.toast.show{opacity:1;visibility:visible;transform:translateX(-50%) translateY(0);}
</style>
</head>
<body>
<!-- 顶部导航栏 -->
<header class="top-bar">
<div class="top-bar__logo">
<svg viewBox="0 0 28 28" fill="none"><rect width="28" height="28" rx="6" fill="#1890FF"/><path d="M7 14h14M14 7v14" stroke="#fff" stroke-width="2.5" stroke-linecap="round"/></svg>
营养管理
</div>
<nav class="top-bar__nav">
<a href="trace-query.html">溯源总览</a>
<a href="arc-employee.html">档案</a>
<a href="farm-land.html">绿色种采</a>
<a href="sup-hygiene-check.html" class="active">卫生供应</a>
<a href="prod-qc-daily.html">健康生产</a>
<a href="din-dict-mgmt.html">营养用餐</a>
<a href="ano-dirty.html">异常事件</a>
</nav>
<div class="top-bar__right">
<a class="btn-back" href="../../index.html">← 返回首页</a>
<div class="avatar"></div>
<span>系统管理员 ▾</span>
</div>
</header>
<!-- 侧边栏:卫生供应 -->
<aside class="sidebar">
<div class="sidebar-menu__title">卫生供应</div>
<a href="sup-hygiene-check.html" class="sidebar-item"><span class="mi">🔬</span>卫生检测</a>
<a href="sup-warehouse.html" class="sidebar-item"><span class="mi">🏭</span>仓储管理</a>
<a href="sup-in-raw.html" class="sidebar-item"><span class="mi">📥</span>毛菜入库</a>
<a href="sup-in-clean.html" class="sidebar-item"><span class="mi">🥬</span>净菜加工</a>
<a href="sup-in-cleanin.html" class="sidebar-item"><span class="mi">📦</span>净菜入库</a>
<a href="sup-pkg-label.html" class="sidebar-item"><span class="mi">🏷️</span>净菜包装</a>
<a href="sup-clean-internal.html" class="sidebar-item"><span class="mi">🏠</span>净菜内供</a>
<a href="sup-clean-external.html" class="sidebar-item"><span class="mi">🚛</span>净菜外售</a>
<div class="sidebar-subgroup">
<div class="sidebar-subgroup__header" onclick="toggleSubgroup(this)">
<svg class="arrow" viewBox="0 0 10 10" fill="none"><path d="M3 1l4 4-4 4" stroke-width="1.5"/></svg>
📊 数据分析
</div>
<div class="sidebar-subgroup__body">
<a href="sup-biz-analysis.html" class="sidebar-item"><span class="mi">📈</span>经营分析</a>
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item active"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容区 -->
<main class="main">
<!-- Tab 切换 -->
<div class="tabs" id="tabs">
<div class="tab active" data-idx="0" onclick="switchTab(0, this)">毛菜加工任务 <span class="tab__count" id="tabCount-0"></span></div>
<div class="tab" data-idx="1" onclick="switchTab(1, this)">净菜加工任务 <span class="tab__count" id="tabCount-1"></span></div>
<div class="tab" data-idx="2" onclick="switchTab(2, this)">净菜组配任务 <span class="tab__count" id="tabCount-2"></span></div>
<div class="tab" data-idx="3" onclick="switchTab(3, this)">净菜包装任务 <span class="tab__count" id="tabCount-3"></span></div>
</div>
<!-- 筛选栏 -->
<div class="filter-bar">
<div class="filter-item"><label>任务编号</label><input class="filter-input" type="text" id="fTaskNo" placeholder="请输入任务编号"></div>
<div class="filter-item"><label>任务状态</label><select class="filter-select" id="fStatus"></select></div>
<div class="filter-item"><label>执行人</label><input class="filter-input" type="text" id="fExecutor" placeholder="请输入执行人"></div>
<div class="filter-item"><label>生成时间</label><input class="filter-input" type="date" id="fCreatedStart"></div>
<div class="filter-item"><label></label><input class="filter-input" type="date" id="fCreatedEnd"></div>
<button class="btn btn-primary" onclick="doQuery()">查询</button>
<button class="btn btn-default" onclick="doReset()">重置</button>
</div>
<!-- 操作栏 -->
<div class="action-bar">
<button class="btn btn-primary" onclick="exportList()"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><path d="M2 10v2h10v-2M7 2v7M4.5 6.5L7 9l2.5-2.5" stroke="#fff" stroke-width="1.4" stroke-linecap="round" stroke-linejoin="round"/></svg>导出列表数据</button>
<button class="btn btn-default" onclick="viewExport()"><svg width="14" height="14" viewBox="0 0 14 14" fill="none"><rect x="2" y="2" width="10" height="10" rx="1.5" stroke="currentColor" stroke-width="1.4"/><path d="M4 5h6M4 7.5h4" stroke="currentColor" stroke-width="1.2" stroke-linecap="round"/></svg>查看导出任务</button>
</div>
<!-- 数据表格 -->
<div class="table-card">
<div class="table-card__header">
<div class="table-card__title" id="tableTitle">毛菜加工任务</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>
</tr></thead>
<tbody id="taskTbody"></tbody>
</table>
</div>
<div class="pagination">
<span id="pageInfo">显示 0 条</span>
<button class="page-btn"></button>
<button class="page-btn active">1</button>
<button class="page-btn"></button>
</div>
</div>
</main>
<div class="toast" id="toast"></div>
<script>
/* ===== 侧边栏子菜单组折叠 ===== */
function toggleSubgroup(el){
var sg=el.parentElement;
sg.classList.toggle('open');
}
/* ===== 状态 → 标签样式映射 ===== */
var STATUS_TAG={
'pending':'tag-orange', /* 未开始 */
'processing':'tag-blue', /* 进行中 */
'done':'tag-green' /* 已完成 */
};
/* ===== 四类任务数据 ===== */
/* 明细项统一结构:{name 名称, spec 规格/要求, state 进度/状态} */
var TASK_TABS=[
{
label:'毛菜加工任务',
device:'毛菜加工秤',
statusOptions:['全部','待处理','已完成'],
tasks:[
{ taskNo:'RW-20260613-001', refNo:'—', content:'黄瓜、土豆、西红柿 等3种食材', status:'待处理', statusType:'pending', executor:'—', createdAt:'2026-06-13 08:00', deadline:'2026-06-13 11:00', finishedAt:'—',
detail:[
{ name:'黄瓜', spec:'需 2000g', state:'已录 2000g · 截止 10:00' },
{ name:'土豆', spec:'需 2500g', state:'已录 2500g · 截止 10:30' },
{ name:'西红柿', spec:'需 1750g', state:'已录 1750g · 截止 11:00' }
] },
{ taskNo:'RW-20260613-002', refNo:'—', content:'胡萝卜、小番茄 等2种食材', status:'待处理', statusType:'pending', executor:'—', createdAt:'2026-06-13 08:30', deadline:'2026-06-13 14:00', finishedAt:'—',
detail:[
{ name:'胡萝卜', spec:'需 1000g', state:'已录 1000g · 截止 11:30' },
{ name:'小番茄', spec:'需 750g', state:'已录 750g · 截止 14:00' }
] },
{ taskNo:'RW-20260613-003', refNo:'—', content:'大白菜、娃娃菜、土豆 等3种食材', status:'已完成', statusType:'done', executor:'张三丰', createdAt:'2026-06-13 07:30', deadline:'2026-06-13 09:30', finishedAt:'2026-06-13 09:45',
detail:[
{ name:'大白菜', spec:'需 4000g', state:'已录 4000g' },
{ name:'娃娃菜', spec:'需 1250g', state:'已录 1250g' },
{ name:'土豆', spec:'需 1500g', state:'已录 1500g' }
] }
]
},
{
label:'净菜加工任务',
device:'净菜加工秤',
statusOptions:['全部','待加工','进行中','已完成'],
tasks:[
{ taskNo:'CW-20260617-001', refNo:'—', content:'土豆、胡萝卜、黄瓜 等3种食材', status:'进行中', statusType:'processing', executor:'赵六', createdAt:'2026-06-17 08:00', deadline:'2026-06-17 11:30', finishedAt:'—',
detail:[
{ name:'土豆', spec:'35×1×1mm · 长条 · 平刀', state:'已加工 3.2/5.0斤' },
{ name:'胡萝卜', spec:'20×1×1mm · 细丝 · 平刀', state:'已加工 1.5/2.0斤' },
{ name:'黄瓜', spec:'30×30×3mm · 圆片 · 平刀', state:'已加工 2.8/4.0斤' }
] },
{ taskNo:'CW-20260617-002', refNo:'—', content:'大白菜、西红柿 等2种食材', status:'待加工', statusType:'pending', executor:'—', createdAt:'2026-06-17 10:00', deadline:'2026-06-17 14:00', finishedAt:'—',
detail:[
{ name:'大白菜', spec:'50×30×30mm · 宽段 · 平刀', state:'未加工' },
{ name:'西红柿', spec:'25×25×20mm · 楔形块 · 平刀', state:'未加工' }
] },
{ taskNo:'CW-20260617-003', refNo:'—', content:'芹菜、洋葱 等2种食材', status:'已完成', statusType:'done', executor:'赵六', createdAt:'2026-06-17 07:30', deadline:'2026-06-17 09:00', finishedAt:'2026-06-17 09:15',
detail:[
{ name:'芹菜', spec:'40×10×10mm · 宽段 · 平刀', state:'已加工 3.0/3.0斤' },
{ name:'洋葱', spec:'30×2×2mm · 细丝 · 平刀', state:'已加工 2.0/2.0斤' }
] }
]
},
{
label:'净菜组配任务',
device:'净菜组配秤',
statusOptions:['全部','待组配','已完成'],
tasks:[
{ taskNo:'T-001', refNo:'PO-20260616-001', content:'宫保鸡丁套餐 等1个餐品净菜包', status:'待组配', statusType:'pending', executor:'—', createdAt:'2026-06-16 08:00', deadline:'2026-06-17 11:30', finishedAt:'—',
detail:[
{ name:'宫保鸡丁套餐', spec:'大份 800g/份 · 3份', state:'待组配' }
] },
{ taskNo:'T-002', refNo:'PO-20260616-002', content:'鱼香肉丝套餐、番茄炒蛋套餐 等2个餐品净菜包', status:'待组配', statusType:'pending', executor:'—', createdAt:'2026-06-16 08:30', deadline:'2026-06-17 12:00', finishedAt:'—',
detail:[
{ name:'鱼香肉丝套餐', spec:'大份 800g/份 · 2份', state:'待组配' },
{ name:'番茄炒蛋套餐', spec:'标准份 500g/份 · 2份', state:'待组配' }
] },
{ taskNo:'T-003', refNo:'PO-20260616-003', content:'番茄炒蛋套餐 等1个餐品净菜包', status:'已完成', statusType:'done', executor:'李四', createdAt:'2026-06-16 07:30', deadline:'2026-06-17 14:30', finishedAt:'2026-06-17 10:20',
detail:[
{ name:'番茄炒蛋套餐', spec:'大份 500g/份 · 4份', state:'已完成' }
] },
{ taskNo:'T-004', refNo:'PO-20260616-004', content:'凉拌黄瓜套餐 等1个餐品净菜包', status:'已完成', statusType:'done', executor:'李四', createdAt:'2026-06-16 09:00', deadline:'2026-06-17 16:00', finishedAt:'2026-06-17 15:40',
detail:[
{ name:'凉拌黄瓜套餐', spec:'标准份 500g/份 · 5份', state:'已完成' }
] }
]
},
{
label:'净菜包装任务',
device:'净菜包装贴标秤',
statusOptions:['全部','待包装','待发货','已发货'],
tasks:[
{ taskNo:'L-001', refNo:'PO-20260625-001', content:'土豆、胡萝卜、宫保鸡丁套餐 等3个净菜包', status:'待包装', statusType:'pending', executor:'—', createdAt:'2026-06-25 08:00', deadline:'2026-06-25 11:30', finishedAt:'—',
detail:[
{ name:'土豆', spec:'500g/袋 · 细丝', state:'待包装' },
{ name:'胡萝卜', spec:'500g/袋 · 菱形片', state:'待包装' },
{ name:'宫保鸡丁套餐', spec:'大份 800g/份', state:'待包装' }
] },
{ taskNo:'L-002', refNo:'PO-20260625-002', content:'白菜、鱼香肉丝套餐 等2个净菜包', status:'待包装', statusType:'pending', executor:'—', createdAt:'2026-06-25 08:20', deadline:'2026-06-25 12:00', finishedAt:'—',
detail:[
{ name:'白菜', spec:'1000g/袋 · 段切', state:'待包装' },
{ name:'鱼香肉丝套餐', spec:'大份 800g/份', state:'待包装' }
] },
{ taskNo:'L-003', refNo:'PO-20260625-003', content:'番茄炒蛋套餐 等1个净菜包', status:'待包装', statusType:'pending', executor:'—', createdAt:'2026-06-25 08:40', deadline:'2026-06-25 14:30', finishedAt:'—',
detail:[
{ name:'番茄炒蛋套餐', spec:'500g/份 · 真空袋', state:'待包装' }
] },
{ taskNo:'L-D01', refNo:'PO-20260624-001', content:'黄瓜、凉拌黄瓜套餐 等2个净菜包', status:'待发货', statusType:'processing', executor:'刘九', createdAt:'2026-06-24 08:00', deadline:'2026-06-24 10:30', finishedAt:'—',
detail:[
{ name:'黄瓜', spec:'500g/袋 · 薄片', state:'已包装' },
{ name:'凉拌黄瓜套餐', spec:'600g/盒 · 保鲜盒', state:'已包装' }
] },
{ taskNo:'L-D02', refNo:'PO-20260624-002', content:'芹菜、芹菜炒肉套餐 等2个净菜包', status:'待发货', statusType:'processing', executor:'陈十', createdAt:'2026-06-24 09:00', deadline:'2026-06-24 14:00', finishedAt:'—',
detail:[
{ name:'芹菜', spec:'500g/袋 · 条', state:'已包装' },
{ name:'芹菜炒肉套餐', spec:'大份 800g/份', state:'已包装' }
] },
{ taskNo:'L-S01', refNo:'PO-20260623-001', content:'西红柿、番茄牛腩套餐 等2个净菜包', status:'已发货', statusType:'done', executor:'王五', createdAt:'2026-06-23 08:00', deadline:'2026-06-23 09:00', finishedAt:'2026-06-24 11:00',
detail:[
{ name:'西红柿', spec:'500g/袋 · 滚刀块', state:'已包装' },
{ name:'番茄牛腩套餐', spec:'大份 800g/份', state:'已包装' }
] }
]
}
];
var currentTabIdx=0;
/* ===== 渲染状态下拉选项(随 Tab 切换) ===== */
function renderStatusOptions(){
var sel=document.getElementById('fStatus');
var opts=TASK_TABS[currentTabIdx].statusOptions;
sel.innerHTML=opts.map(function(o){return '<option>'+o+'</option>';}).join('');
}
/* ===== 状态标签 HTML ===== */
function statusTag(statusType,text){
var cls=STATUS_TAG[statusType]||'tag-gray';
return '<span class="tag '+cls+'">'+text+'</span>';
}
/* ===== 渲染表格 ===== */
function renderTable(){
var tab=TASK_TABS[currentTabIdx];
var tbody=document.getElementById('taskTbody');
var html='';
tab.tasks.forEach(function(t){
html+='<tr>'
+'<td>'+t.taskNo+'</td>'
+'<td>'+t.refNo+'</td>'
+'<td>'+t.content+'</td>'
+'<td>'+statusTag(t.statusType,t.status)+'</td>'
+'<td>'+t.executor+'</td>'
+'<td>'+t.createdAt+'</td>'
+'<td>'+t.deadline+'</td>'
+'<td>'+t.finishedAt+'</td>'
+'<td class="td-actions"><span class="link" onclick="showDetail(\''+t.taskNo+'\')">详情</span></td>'
+'</tr>';
});
tbody.innerHTML=html;
document.getElementById('tableTitle').textContent=tab.label;
document.getElementById('pageInfo').textContent='显示 '+tab.tasks.length+' 条';
}
/* ===== 更新 Tab 计数 ===== */
function renderTabCounts(){
TASK_TABS.forEach(function(tab,i){
document.getElementById('tabCount-'+i).textContent=tab.tasks.length;
});
}
/* ===== 切换 Tab ===== */
function switchTab(idx,el){
currentTabIdx=idx;
document.querySelectorAll('.tab').forEach(function(t){t.classList.remove('active');});
el.classList.add('active');
renderStatusOptions();
doReset();
renderTable();
}
/* ===== 查询(简单前端过滤:任务编号/执行人关键字 + 状态精确匹配) ===== */
function doQuery(){
var tab=TASK_TABS[currentTabIdx];
var kwNo=document.getElementById('fTaskNo').value.trim();
var kwExe=document.getElementById('fExecutor').value.trim();
var status=document.getElementById('fStatus').value;
var list=tab.tasks.filter(function(t){
if(kwNo && t.taskNo.indexOf(kwNo)===-1) return false;
if(kwExe && t.executor.indexOf(kwExe)===-1) return false;
if(status && status!=='全部' && t.status!==status) return false;
return true;
});
var tbody=document.getElementById('taskTbody');
var html='';
list.forEach(function(t){
html+='<tr>'
+'<td>'+t.taskNo+'</td>'
+'<td>'+t.refNo+'</td>'
+'<td>'+t.content+'</td>'
+'<td>'+statusTag(t.statusType,t.status)+'</td>'
+'<td>'+t.executor+'</td>'
+'<td>'+t.createdAt+'</td>'
+'<td>'+t.deadline+'</td>'
+'<td>'+t.finishedAt+'</td>'
+'<td class="td-actions"><span class="link" onclick="showDetail(\''+t.taskNo+'\')">详情</span></td>'
+'</tr>';
});
tbody.innerHTML=html;
document.getElementById('pageInfo').textContent='显示 '+list.length+' 条';
}
/* ===== 重置 ===== */
function doReset(){
document.getElementById('fTaskNo').value='';
document.getElementById('fExecutor').value='';
document.getElementById('fCreatedStart').value='';
document.getElementById('fCreatedEnd').value='';
var sel=document.getElementById('fStatus');
sel.selectedIndex=0;
renderTable();
}
/* ===== 导出列表数据(占位) ===== */
function exportList(){
showToast('已导出「'+TASK_TABS[currentTabIdx].label+'」列表数据');
}
/* ===== 查看导出任务(占位) ===== */
function viewExport(){
showToast('查看导出任务');
}
/* ===== 详情抽屉 ===== */
var Drawer={
open:function(title,bodyHtml){
this.close();
var overlay=document.createElement('div');
overlay.className='drawer-overlay';
overlay.innerHTML='<div class="drawer"><div class="drawer__header"><div class="drawer__title">'+title+'</div><button class="drawer__close" onclick="Drawer.close()">&times;</button></div><div class="drawer__body">'+bodyHtml+'</div></div>';
overlay.addEventListener('click',function(e){if(e.target===overlay)Drawer.close();});
document.body.appendChild(overlay);
},
close:function(){
var o=document.querySelector('.drawer-overlay');
if(!o)return;
o.classList.add('closing');
setTimeout(function(){o.remove();},200);
}
};
/* 根据任务编号查找任务 */
function findTask(taskNo){
for(var i=0;i<TASK_TABS.length;i++){
var found=TASK_TABS[i].tasks.filter(function(t){return t.taskNo===taskNo;});
if(found.length) return { tab:TASK_TABS[i], task:found[0] };
}
return null;
}
function showDetail(taskNo){
var r=findTask(taskNo);
if(!r) return;
var tab=r.tab, t=r.task;
/* 任务信息区 */
var fields=
'<div class="drawer-field"><div class="drawer-field__label">任务编号</div><div class="drawer-field__value">'+t.taskNo+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">终端设备</div><div class="drawer-field__value">'+tab.device+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">关联单号</div><div class="drawer-field__value">'+t.refNo+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">任务状态</div><div class="drawer-field__value">'+statusTag(t.statusType,t.status)+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">执行人</div><div class="drawer-field__value">'+t.executor+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">生成时间</div><div class="drawer-field__value">'+t.createdAt+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">截止时间</div><div class="drawer-field__value">'+t.deadline+'</div></div>'
+'<div class="drawer-field"><div class="drawer-field__label">完成时间</div><div class="drawer-field__value">'+t.finishedAt+'</div></div>';
/* 任务明细区 */
var rows='';
t.detail.forEach(function(d){
rows+='<tr><td>'+d.name+'</td><td>'+d.spec+'</td><td>'+d.state+'</td></tr>';
});
var detailTable='<table class="detail-table"><thead><tr><th>名称</th><th>规格/要求</th><th>进度/状态</th></tr></thead><tbody>'+rows+'</tbody></table>';
var html='<div class="drawer-section"><div class="drawer-section__title">任务信息</div><div class="drawer-fields">'+fields+'</div></div>'
+'<div class="drawer-section"><div class="drawer-section__title">任务明细</div>'+detailTable+'</div>';
Drawer.open('任务详情 — '+t.taskNo, html);
}
/* ===== Toast ===== */
function showToast(msg){
var el=document.getElementById('toast');
el.textContent=msg;
el.classList.add('show');
clearTimeout(el._timer);
el._timer=setTimeout(function(){el.classList.remove('show');},2000);
}
/* ===== 初始化 ===== */
renderStatusOptions();
renderTabCounts();
renderTable();
</script>
</body>
</html>
+1
View File
@@ -230,6 +230,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<a href="sup-process-analysis.html" class="sidebar-item"><span class="mi">🔧</span>加工分析</a>
</div>
</div>
<a href="sup-task-center.html" class="sidebar-item"><span class="mi">📋</span>任务中心</a>
</aside>
<!-- 主内容 -->