feat: 新增库存管理模块(库存总览、出入库、采购、估清、效期)

- 库存总览:原料列表、低库存/缺货预警、新增原料抽屉
- 出入库管理:入库/出库/盘点三个tab,录入抽屉
- 采购管理:采购单流转+供应商目录,新建采购单抽屉
- 估清管理:自动/手动模式切换,原料→菜品关联映射
- 效期管理:FIFO提醒,批次按紧急度分级
- 侧边栏和pageMap同步更新
This commit is contained in:
2026-02-12 17:14:49 +08:00
parent b88155bf08
commit 98dd84fef9
6 changed files with 1612 additions and 3 deletions

249
pages/inv-expiry.html Normal file
View File

@@ -0,0 +1,249 @@
<!-- 效期管理页 -->
<style>
.ive-fifo{display:flex;align-items:center;gap:10px;padding:12px 18px;background:color-mix(in srgb, var(--primary) 8%, #fff);border:1px solid color-mix(in srgb, var(--primary) 20%, #fff);border-radius:var(--g-radius);margin-bottom:16px;font-size:13px;color:var(--primary);font-weight:500;}
.ive-fifo svg{width:18px;height:18px;flex-shrink:0;}
.ive-stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-bottom:16px;}
.ive-stat{display:flex;align-items:center;gap:14px;padding:16px 20px;background:#fff;border-radius:var(--g-radius);box-shadow:var(--g-shadow-sm);transition:var(--g-transition);border-left:3px solid transparent;}
.ive-stat:hover{box-shadow:var(--g-shadow-md);}
.ive-stat-icon{width:40px;height:40px;border-radius:10px;display:flex;align-items:center;justify-content:center;flex-shrink:0;}
.ive-stat-icon svg{width:20px;height:20px;}
.ive-stat-num{font-size:22px;font-weight:700;line-height:1.2;}
.ive-stat-label{font-size:12px;color:var(--g-text-muted);margin-top:2px;}
.ive-stat-red{border-left-color:var(--g-danger);}
.ive-stat-red .ive-stat-icon{background:#fff1f0;color:var(--g-danger);}
.ive-stat-red .ive-stat-num{color:var(--g-danger);}
.ive-stat-orange{border-left-color:#fa8c16;}
.ive-stat-orange .ive-stat-icon{background:#fff7e6;color:#fa8c16;}
.ive-stat-orange .ive-stat-num{color:#fa8c16;}
.ive-stat-yellow{border-left-color:#faad14;}
.ive-stat-yellow .ive-stat-icon{background:#fffbe6;color:#faad14;}
.ive-stat-yellow .ive-stat-num{color:#faad14;}
.ive-stat-green{border-left-color:var(--g-success);}
.ive-stat-green .ive-stat-icon{background:#f6ffed;color:var(--g-success);}
.ive-stat-green .ive-stat-num{color:var(--g-success);}
.ive-toolbar{display:flex;align-items:center;gap:10px;margin-bottom:16px;flex-wrap:wrap;padding:12px 16px;background:#fff;border-radius:var(--g-radius);box-shadow:var(--g-shadow-sm);}
.ive-toolbar select{height:34px;padding:0 10px;border:1px solid var(--g-border);border-radius:var(--g-radius-sm);font-size:13px;outline:none;background:#fff;min-width:140px;cursor:pointer;transition:var(--g-transition);}
.ive-toolbar select:focus{border-color:var(--primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent);}
.ive-toolbar .ive-search{height:34px;padding:0 12px;border:1px solid var(--g-border);border-radius:var(--g-radius-sm);font-size:13px;outline:none;width:200px;transition:var(--g-transition);}
.ive-toolbar .ive-search:focus{border-color:var(--primary);box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent);}
.ive-toolbar .ive-spacer{flex:1;}
.ive-row-expired{background:#fff1f0 !important;}
.ive-row-3day{background:#fff7e6 !important;}
.ive-row-7day{background:#fffbe6 !important;}
.ive-days-expired{color:var(--g-danger);font-weight:600;font-size:12px;}
.ive-days-urgent{color:#fa8c16;font-weight:600;}
@media(max-width:800px){.ive-stats{grid-template-columns:repeat(2,1fr);}}
@media(max-width:500px){.ive-stats{grid-template-columns:1fr;}}
</style>
<!-- FIFO 提醒条 -->
<div class="ive-fifo">
<i data-lucide="info"></i>
<span>遵循先进先出原则,请优先使用临期批次的原料</span>
</div>
<!-- 统计卡片 -->
<div class="ive-stats">
<div class="ive-stat ive-stat-red">
<div class="ive-stat-icon"><i data-lucide="alert-circle"></i></div>
<div>
<div class="ive-stat-num">1 <span style="font-size:13px;font-weight:500;"></span></div>
<div class="ive-stat-label">已过期</div>
</div>
</div>
<div class="ive-stat ive-stat-orange">
<div class="ive-stat-icon"><i data-lucide="clock"></i></div>
<div>
<div class="ive-stat-num">3 <span style="font-size:13px;font-weight:500;"></span></div>
<div class="ive-stat-label">3天内到期</div>
</div>
</div>
<div class="ive-stat ive-stat-yellow">
<div class="ive-stat-icon"><i data-lucide="timer"></i></div>
<div>
<div class="ive-stat-num">5 <span style="font-size:13px;font-weight:500;"></span></div>
<div class="ive-stat-label">7天内到期</div>
</div>
</div>
<div class="ive-stat ive-stat-green">
<div class="ive-stat-icon"><i data-lucide="check-circle"></i></div>
<div>
<div class="ive-stat-num">38 <span style="font-size:13px;font-weight:500;"></span></div>
<div class="ive-stat-label">正常</div>
</div>
</div>
</div>
<!-- 筛选工具栏 -->
<div class="ive-toolbar">
<select>
<option>全部分类</option>
<option>肉类</option>
<option>蔬菜</option>
<option>调料</option>
<option>饮品原料</option>
<option>包装</option>
</select>
<select>
<option>全部状态</option>
<option>已过期</option>
<option>3天内到期</option>
<option>7天内到期</option>
<option>正常</option>
</select>
<div class="ive-spacer"></div>
<input class="ive-search" type="text" placeholder="搜索原料名称">
</div>
<!-- 批次列表 -->
<div class="g-card" style="padding:0;overflow:hidden;">
<table class="g-table" style="margin:0;">
<thead>
<tr>
<th>原料名称</th>
<th>批次号</th>
<th>分类</th>
<th>入库日期</th>
<th>保质期至</th>
<th>剩余天数</th>
<th>库存数量</th>
<th>状态</th>
<th style="width:130px;">操作</th>
</tr>
</thead>
<tbody>
<tr class="ive-row-expired">
<td style="font-weight:600;">鲜牛奶</td>
<td>B20260210</td>
<td>饮品原料</td>
<td>2026-02-10</td>
<td>2026-02-13</td>
<td><span class="ive-days-expired">已过期1天</span></td>
<td>12 瓶</td>
<td><span class="g-tag g-tag-red">已过期</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr class="ive-row-3day">
<td style="font-weight:600;">生菜</td>
<td>B20260211</td>
<td>蔬菜</td>
<td>2026-02-11</td>
<td>2026-02-14</td>
<td><span class="ive-days-urgent">2 天</span></td>
<td>8 kg</td>
<td><span class="g-tag g-tag-orange">3天内</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr class="ive-row-3day">
<td style="font-weight:600;">鸡胸肉</td>
<td>B20260209</td>
<td>肉类</td>
<td>2026-02-09</td>
<td>2026-02-15</td>
<td><span class="ive-days-urgent">3 天</span></td>
<td>15 kg</td>
<td><span class="g-tag g-tag-orange">3天内</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr class="ive-row-7day">
<td style="font-weight:600;">西红柿</td>
<td>B20260210</td>
<td>蔬菜</td>
<td>2026-02-10</td>
<td>2026-02-16</td>
<td><span class="ive-days-urgent">4 天</span></td>
<td>10 kg</td>
<td><span class="g-tag g-tag-orange">7天内</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr class="ive-row-7day">
<td style="font-weight:600;">豆腐</td>
<td>B20260211</td>
<td>蔬菜</td>
<td>2026-02-11</td>
<td>2026-02-17</td>
<td><span class="ive-days-urgent">5 天</span></td>
<td>20 盒</td>
<td><span class="g-tag g-tag-orange">7天内</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr class="ive-row-7day">
<td style="font-weight:600;">猪肉</td>
<td>B20260208</td>
<td>肉类</td>
<td>2026-02-08</td>
<td>2026-02-18</td>
<td><span class="ive-days-urgent">6 天</span></td>
<td>25 kg</td>
<td><span class="g-tag g-tag-orange">7天内</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr>
<td style="font-weight:600;">酱油</td>
<td>B20260101</td>
<td>调料</td>
<td>2026-01-01</td>
<td>2026-06-30</td>
<td>138 天</td>
<td>6 瓶</td>
<td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr>
<td style="font-weight:600;">食用油</td>
<td>B20260115</td>
<td>调料</td>
<td>2026-01-15</td>
<td>2026-07-15</td>
<td>153 天</td>
<td>4 桶</td>
<td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr>
<td style="font-weight:600;">咖啡豆</td>
<td>B20260201</td>
<td>饮品原料</td>
<td>2026-02-01</td>
<td>2026-08-01</td>
<td>170 天</td>
<td>10 kg</td>
<td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
<tr>
<td style="font-weight:600;">外卖盒</td>
<td>B20260201</td>
<td>包装</td>
<td>2026-02-01</td>
<td></td>
<td></td>
<td>500 个</td>
<td><span class="g-tag g-tag-gray">无期限</span></td>
<td><a class="g-action g-action-danger" href="javascript:;">报损</a> <a class="g-action" href="javascript:;">优先使用</a></td>
</tr>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="g-pagination" style="margin-top:16px;">
<span style="font-size:13px;color:var(--g-text-muted);">共 47 条</span>
<div style="display:flex;gap:6px;margin-left:auto;">
<button class="g-page-btn" disabled>&lt;</button>
<button class="g-page-btn active">1</button>
<button class="g-page-btn">2</button>
<button class="g-page-btn">3</button>
<button class="g-page-btn">4</button>
<button class="g-page-btn">5</button>
<button class="g-page-btn">&gt;</button>
</div>
</div>
<script>
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>

445
pages/inv-inout.html Normal file
View File

@@ -0,0 +1,445 @@
<!-- 出入库管理 — inv-inout.html -->
<style>
/* ---- page-private: ivi- prefix ---- */
.ivi-toolbar {
background:#fff; border-radius:var(--g-radius); padding:14px 18px;
display:flex; flex-wrap:wrap; gap:10px; align-items:center;
box-shadow:var(--g-shadow-sm); border:1px solid var(--g-border); margin-bottom:16px;
}
.ivi-toolbar select,
.ivi-toolbar input[type="date"] {
height:32px; padding:0 10px; border:1px solid #e5e7eb; border-radius:var(--g-radius-sm,6px);
font-size:13px; outline:none; transition:var(--g-transition); background:#fff; color:var(--g-text);
}
.ivi-toolbar select:focus,
.ivi-toolbar input[type="date"]:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
.ivi-toolbar select { min-width:120px; }
.ivi-date-sep { color:var(--g-text-muted); font-size:13px; line-height:32px; }
.ivi-toolbar-right { margin-left:auto; display:flex; gap:8px; align-items:center; }
.ivi-panel {
background:#fff; border-radius:var(--g-radius); box-shadow:var(--g-shadow-sm);
padding:18px 20px;
}
.ivi-seg-wrap { margin-bottom:16px; }
.ivi-table-card {
background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border);
overflow:hidden;
}
.ivi-table-card .g-table th { white-space:nowrap; }
.ivi-table-card .g-table td { vertical-align:middle; font-size:13px; }
.ivi-mono { font-family:'SF Mono','Cascadia Code','Consolas',monospace; font-size:12px; color:var(--g-text-secondary); }
.ivi-amount { font-weight:600; white-space:nowrap; }
.ivi-amount.positive { color:var(--g-success); }
.ivi-amount.negative { color:var(--g-danger); }
.ivi-detail-cell { max-width:200px; white-space:nowrap; overflow:hidden; text-overflow:ellipsis; font-size:12px; color:var(--g-text-secondary); }
/* 新增入库抽屉 */
.ivi-drawer { width:520px; }
.ivi-material-row {
display:flex; gap:8px; align-items:center; margin-bottom:10px;
}
.ivi-material-row select,
.ivi-material-row input {
height:34px; padding:0 10px; border:1px solid #e5e7eb; border-radius:var(--g-radius-sm,6px);
font-size:13px; outline:none; transition:var(--g-transition); background:#fff; color:var(--g-text);
}
.ivi-material-row select:focus,
.ivi-material-row input:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
.ivi-material-row select { flex:2; min-width:0; }
.ivi-material-row input { flex:1; min-width:0; }
.ivi-subtotal {
flex:0 0 70px; text-align:right; font-size:13px; font-weight:600; color:var(--g-text);
}
.ivi-del-btn {
flex-shrink:0; width:30px; height:30px; border:none; background:none;
color:var(--g-text-muted); cursor:pointer; border-radius:6px; display:flex; align-items:center; justify-content:center;
transition:var(--g-transition);
}
.ivi-del-btn:hover { background:color-mix(in srgb, var(--g-danger) 8%, #fff); color:var(--g-danger); }
.ivi-add-row {
width:100%; height:36px; border:1px dashed #d9d9d9; border-radius:var(--g-radius-sm,6px);
background:#fafafa; color:var(--primary); font-size:13px; cursor:pointer;
display:flex; align-items:center; justify-content:center; gap:4px;
transition:var(--g-transition);
}
.ivi-add-row:hover { border-color:var(--primary); background:var(--primary-light,hsl(212,100%,95%)); }
.ivi-material-header {
display:flex; gap:8px; align-items:center; margin-bottom:8px; font-size:12px; color:var(--g-text-muted); font-weight:500;
}
.ivi-material-header span:nth-child(1) { flex:2; }
.ivi-material-header span:nth-child(2) { flex:1; }
.ivi-material-header span:nth-child(3) { flex:1; }
.ivi-material-header span:nth-child(4) { flex:0 0 70px; text-align:right; }
.ivi-material-header span:nth-child(5) { flex:0 0 30px; }
</style>
<!-- 面板 -->
<div class="ivi-panel">
<!-- 分段控制器 -->
<div class="ivi-seg-wrap">
<div class="g-seg">
<div class="g-seg-item active" onclick="switchIviTab(this)" data-tab="in">入库记录</div>
<div class="g-seg-item" onclick="switchIviTab(this)" data-tab="out">出库记录</div>
<div class="g-seg-item" onclick="switchIviTab(this)" data-tab="check">盘点记录</div>
</div>
</div>
<!-- ========== Tab1: 入库记录 ========== -->
<div id="iviTabIn">
<div class="ivi-toolbar" style="box-shadow:none;border:none;padding:0 0 14px;">
<input type="date" value="2026-01-01">
<span class="ivi-date-sep"></span>
<input type="date" value="2026-02-12">
<select>
<option>全部供应商</option>
<option>鑫源食材配送</option>
<option>绿野农产品</option>
<option>海鲜直供站</option>
</select>
<div class="ivi-toolbar-right">
<button class="g-btn g-btn-primary" onclick="openIviDrawer()"><i data-lucide="plus" style="width:14px;height:14px;"></i> 新增入库</button>
</div>
</div>
<div class="ivi-table-card">
<table class="g-table">
<thead>
<tr>
<th>入库单号</th>
<th>日期</th>
<th>供应商</th>
<th>原料明细</th>
<th>总金额</th>
<th>经办人</th>
<th style="width:60px;">操作</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ivi-mono">RK20260212001</td>
<td>2026-02-12</td>
<td>鑫源食材配送</td>
<td class="ivi-detail-cell">五花肉 10kg、牛腩 8kg <span style="color:var(--primary);cursor:pointer;">等3项</span></td>
<td class="ivi-amount">&yen;2,360.00</td>
<td>张经理</td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">RK20260211002</td>
<td>2026-02-11</td>
<td>绿野农产品</td>
<td class="ivi-detail-cell">生菜 5kg、西红柿 8kg <span style="color:var(--primary);cursor:pointer;">等5项</span></td>
<td class="ivi-amount">&yen;680.00</td>
<td>李主管</td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">RK20260210003</td>
<td>2026-02-10</td>
<td>海鲜直供站</td>
<td class="ivi-detail-cell">鲈鱼 15条、基围虾 5kg</td>
<td class="ivi-amount">&yen;1,850.00</td>
<td>张经理</td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">RK20260209004</td>
<td>2026-02-09</td>
<td>鑫源食材配送</td>
<td class="ivi-detail-cell">鸡胸肉 12kg、排骨 10kg <span style="color:var(--primary);cursor:pointer;">等4项</span></td>
<td class="ivi-amount">&yen;3,120.00</td>
<td>王厨师</td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">RK20260208005</td>
<td>2026-02-08</td>
<td>绿野农产品</td>
<td class="ivi-detail-cell">土豆 20kg、洋葱 10kg</td>
<td class="ivi-amount">&yen;420.00</td>
<td>李主管</td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">RK20260207006</td>
<td>2026-02-07</td>
<td>海鲜直供站</td>
<td class="ivi-detail-cell">三文鱼 8kg、扇贝 3kg <span style="color:var(--primary);cursor:pointer;">等3项</span></td>
<td class="ivi-amount">&yen;2,980.00</td>
<td>张经理</td>
<td><a class="g-action">查看</a></td>
</tr>
</tbody>
</table>
<div class="g-pagination">
<span style="font-size:13px;color:var(--g-text-secondary);margin-right:12px;">共 6 条</span>
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
<button class="g-page-btn active">1</button>
<button class="g-page-btn" disabled><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
</div>
</div>
</div>
<!-- ========== Tab2: 出库记录 ========== -->
<div id="iviTabOut" style="display:none;">
<div class="ivi-toolbar" style="box-shadow:none;border:none;padding:0 0 14px;">
<input type="date" value="2026-01-01">
<span class="ivi-date-sep"></span>
<input type="date" value="2026-02-12">
<select>
<option>全部类型</option>
<option>订单消耗</option>
<option>报损</option>
<option>调拨</option>
<option>其他</option>
</select>
</div>
<div class="ivi-table-card">
<table class="g-table">
<thead>
<tr>
<th>出库单号</th>
<th>日期</th>
<th>类型</th>
<th>原料明细</th>
<th>数量</th>
<th>经办人</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ivi-mono">CK20260212001</td>
<td>2026-02-12</td>
<td><span class="g-tag g-tag-blue">订单消耗</span></td>
<td class="ivi-detail-cell">五花肉、生菜、西红柿</td>
<td>3.5kg / 2kg / 1.5kg</td>
<td>系统自动</td>
</tr>
<tr>
<td class="ivi-mono">CK20260212002</td>
<td>2026-02-12</td>
<td><span class="g-tag g-tag-blue">订单消耗</span></td>
<td class="ivi-detail-cell">鸡胸肉、土豆</td>
<td>2kg / 3kg</td>
<td>系统自动</td>
</tr>
<tr>
<td class="ivi-mono">CK20260211003</td>
<td>2026-02-11</td>
<td><span class="g-tag g-tag-red">报损</span></td>
<td class="ivi-detail-cell">基围虾(变质)</td>
<td>1.2kg</td>
<td>王厨师</td>
</tr>
<tr>
<td class="ivi-mono">CK20260211004</td>
<td>2026-02-11</td>
<td><span class="g-tag g-tag-blue">订单消耗</span></td>
<td class="ivi-detail-cell">牛腩、洋葱、排骨</td>
<td>4kg / 2kg / 3kg</td>
<td>系统自动</td>
</tr>
<tr>
<td class="ivi-mono">CK20260210005</td>
<td>2026-02-10</td>
<td><span class="g-tag g-tag-gray">调拨</span></td>
<td class="ivi-detail-cell">三文鱼(调至分店)</td>
<td>2kg</td>
<td>张经理</td>
</tr>
<tr>
<td class="ivi-mono">CK20260210006</td>
<td>2026-02-10</td>
<td><span class="g-tag g-tag-blue">订单消耗</span></td>
<td class="ivi-detail-cell">鲈鱼、生菜、土豆</td>
<td>3条 / 1.5kg / 2kg</td>
<td>系统自动</td>
</tr>
</tbody>
</table>
<div class="g-pagination">
<span style="font-size:13px;color:var(--g-text-secondary);margin-right:12px;">共 6 条</span>
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
<button class="g-page-btn active">1</button>
<button class="g-page-btn" disabled><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
</div>
</div>
</div>
<!-- ========== Tab3: 盘点记录 ========== -->
<div id="iviTabCheck" style="display:none;">
<div class="ivi-toolbar" style="box-shadow:none;border:none;padding:0 0 14px;">
<input type="date" value="2026-01-01">
<span class="ivi-date-sep"></span>
<input type="date" value="2026-02-12">
<div class="ivi-toolbar-right">
<button class="g-btn g-btn-primary"><i data-lucide="clipboard-list" style="width:14px;height:14px;"></i> 新建盘点</button>
</div>
</div>
<div class="ivi-table-card">
<table class="g-table">
<thead>
<tr>
<th>盘点单号</th>
<th>盘点日期</th>
<th>盘点范围</th>
<th>差异项数</th>
<th>盈亏金额</th>
<th>状态</th>
<th style="width:60px;">操作</th>
</tr>
</thead>
<tbody>
<tr>
<td class="ivi-mono">PD20260212001</td>
<td>2026-02-12</td>
<td>全部</td>
<td>3</td>
<td class="ivi-amount negative">-&yen;186.00</td>
<td><span class="g-tag g-tag-orange">进行中</span></td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">PD20260205002</td>
<td>2026-02-05</td>
<td>肉类</td>
<td>1</td>
<td class="ivi-amount negative">-&yen;95.00</td>
<td><span class="g-tag g-tag-green">已完成</span></td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">PD20260130003</td>
<td>2026-01-30</td>
<td>蔬菜</td>
<td>2</td>
<td class="ivi-amount positive">+&yen;32.00</td>
<td><span class="g-tag g-tag-green">已完成</span></td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td class="ivi-mono">PD20260120004</td>
<td>2026-01-20</td>
<td>全部</td>
<td>5</td>
<td class="ivi-amount negative">-&yen;420.00</td>
<td><span class="g-tag g-tag-green">已完成</span></td>
<td><a class="g-action">查看</a></td>
</tr>
</tbody>
</table>
<div class="g-pagination">
<span style="font-size:13px;color:var(--g-text-secondary);margin-right:12px;">共 4 条</span>
<button class="g-page-btn" disabled><i data-lucide="chevron-left" style="width:14px;height:14px;"></i></button>
<button class="g-page-btn active">1</button>
<button class="g-page-btn" disabled><i data-lucide="chevron-right" style="width:14px;height:14px;"></i></button>
</div>
</div>
</div>
</div>
<!-- ========== 新增入库抽屉 ========== -->
<div class="g-drawer-mask" id="iviDrawerMask" onclick="closeIviDrawer()"></div>
<div class="g-drawer ivi-drawer" id="iviDrawer">
<div class="g-drawer-hd">
<div class="g-drawer-title">新增入库单</div>
<button class="g-drawer-close" onclick="closeIviDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
</div>
<div class="g-drawer-bd">
<!-- 供应商 -->
<div class="g-form-group">
<label class="g-form-label required">供应商</label>
<select class="g-select" style="width:100%;">
<option value="">请选择供应商</option>
<option>鑫源食材配送</option>
<option>绿野农产品</option>
<option>海鲜直供站</option>
</select>
</div>
<!-- 入库日期 -->
<div class="g-form-group">
<label class="g-form-label">入库日期</label>
<input class="g-input" type="date" value="2026-02-12">
</div>
<!-- 原料明细 -->
<div class="g-form-group">
<label class="g-form-label required">原料明细</label>
<div class="ivi-material-header">
<span>原料名称</span>
<span>数量</span>
<span>单价(元)</span>
<span>小计</span>
<span></span>
</div>
<div id="iviMaterialList">
<div class="ivi-material-row">
<select><option>五花肉</option><option>牛腩</option><option>鸡胸肉</option><option>排骨</option><option>生菜</option><option>西红柿</option><option>土豆</option><option>鲈鱼</option><option>基围虾</option></select>
<input type="number" placeholder="数量" value="10">
<input type="number" placeholder="单价" value="32">
<div class="ivi-subtotal">&yen;320</div>
<button class="ivi-del-btn" onclick="this.parentElement.remove()"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>
</div>
<div class="ivi-material-row">
<select><option>牛腩</option><option>五花肉</option><option>鸡胸肉</option><option>排骨</option><option>生菜</option><option>西红柿</option><option>土豆</option><option>鲈鱼</option><option>基围虾</option></select>
<input type="number" placeholder="数量" value="8">
<input type="number" placeholder="单价" value="58">
<div class="ivi-subtotal">&yen;464</div>
<button class="ivi-del-btn" onclick="this.parentElement.remove()"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>
</div>
</div>
<button class="ivi-add-row" onclick="addIviMaterialRow()">
<i data-lucide="plus" style="width:14px;height:14px;"></i> 添加原料
</button>
</div>
<!-- 备注 -->
<div class="g-form-group">
<label class="g-form-label">备注</label>
<textarea class="g-textarea" rows="3" placeholder="请输入备注信息(选填)"></textarea>
</div>
</div>
<div class="g-drawer-ft">
<button class="g-btn" onclick="closeIviDrawer()">取消</button>
<button class="g-btn g-btn-primary">确认入库</button>
</div>
</div>
<script>
/* Tab 切换 */
function switchIviTab(el) {
document.querySelectorAll('.g-seg-item').forEach(function(s){ s.classList.remove('active'); });
el.classList.add('active');
var tab = el.getAttribute('data-tab');
document.getElementById('iviTabIn').style.display = tab === 'in' ? '' : 'none';
document.getElementById('iviTabOut').style.display = tab === 'out' ? '' : 'none';
document.getElementById('iviTabCheck').style.display = tab === 'check' ? '' : 'none';
}
/* 抽屉开关 */
function openIviDrawer() {
document.getElementById('iviDrawerMask').classList.add('open');
document.getElementById('iviDrawer').classList.add('open');
}
function closeIviDrawer() {
document.getElementById('iviDrawerMask').classList.remove('open');
document.getElementById('iviDrawer').classList.remove('open');
}
/* 添加原料行 */
function addIviMaterialRow() {
var html = '<div class="ivi-material-row">'
+ '<select><option value="">请选择原料</option><option>五花肉</option><option>牛腩</option><option>鸡胸肉</option><option>排骨</option><option>生菜</option><option>西红柿</option><option>土豆</option><option>鲈鱼</option><option>基围虾</option></select>'
+ '<input type="number" placeholder="数量">'
+ '<input type="number" placeholder="单价">'
+ '<div class="ivi-subtotal">&yen;0</div>'
+ '<button class="ivi-del-btn" onclick="this.parentElement.remove()"><i data-lucide="trash-2" style="width:14px;height:14px;"></i></button>'
+ '</div>';
document.getElementById('iviMaterialList').insertAdjacentHTML('beforeend', html);
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
}
/* 初始化图标 */
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>

276
pages/inv-overview.html Normal file
View File

@@ -0,0 +1,276 @@
<!-- 库存总览 -->
<style>
.ivo-page { display:flex; flex-direction:column; gap:16px; }
/* 工具栏 */
.ivo-toolbar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.ivo-toolbar-right { margin-left:auto; display:flex; gap:8px; }
.ivo-search { width:220px; }
/* 统计卡片 */
.ivo-stats { display:grid; grid-template-columns:repeat(4,1fr); gap:14px; }
.ivo-stat { background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border); padding:18px 20px; display:flex; align-items:center; gap:14px; transition:var(--g-transition); cursor:default; }
.ivo-stat:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
.ivo-stat-icon { width:42px; height:42px; border-radius:var(--g-radius); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.ivo-stat-icon.blue { background:hsl(212,100%,95%); color:hsl(212,100%,45%); }
.ivo-stat-icon.orange { background:#fff7e6; color:var(--g-warning); }
.ivo-stat-icon.red { background:#fff1f0; color:var(--g-danger); }
.ivo-stat-icon.green { background:#f0fdf4; color:var(--g-success); }
.ivo-stat-info { display:flex; flex-direction:column; gap:4px; }
.ivo-stat-label { font-size:13px; color:var(--g-text-secondary); }
.ivo-stat-value { font-size:24px; font-weight:700; color:var(--g-text); letter-spacing:-0.5px; }
.ivo-stat-value.orange { color:var(--g-warning); }
.ivo-stat-value.red { color:var(--g-danger); }
/* 表格容器 */
.ivo-table-wrap { background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border); overflow:hidden; }
.ivo-table-inner { overflow-x:auto; }
/* 行状态背景 */
.ivo-row-warn td { background:#fffbe6 !important; }
.ivo-row-danger td { background:#fff1f0 !important; }
/* 分页栏 */
.ivo-pager-bar { display:flex; align-items:center; justify-content:space-between; padding:12px 16px; border-top:1px solid var(--g-border); font-size:13px; color:var(--g-text-secondary); }
.ivo-pager-bar .g-select { width:auto; height:28px; font-size:12px; }
</style>
<div class="ivo-page">
<!-- 工具栏 -->
<div class="ivo-toolbar">
<input class="g-input ivo-search" placeholder="搜索原料名称…" />
<select class="g-select" style="width:140px;">
<option>全部分类</option>
<option>肉类</option>
<option>蔬菜</option>
<option>调料</option>
<option>饮品原料</option>
<option>包装耗材</option>
</select>
<select class="g-select" style="width:120px;">
<option>全部状态</option>
<option>正常</option>
<option>低库存</option>
<option>缺货</option>
</select>
<div class="ivo-toolbar-right">
<button class="g-btn" id="ivoBtnPurchase" onclick="ivoGenPurchase()">
<i data-lucide="clipboard-list" style="width:14px;height:14px;"></i> 一键生成采购单
</button>
<button class="g-btn g-btn-primary" onclick="openIvoDrawer()">
<i data-lucide="plus" style="width:14px;height:14px;"></i> 新增原料
</button>
</div>
</div>
<!-- 统计卡片 -->
<div class="ivo-stats">
<div class="ivo-stat">
<div class="ivo-stat-icon blue"><i data-lucide="package" style="width:20px;height:20px;"></i></div>
<div class="ivo-stat-info">
<span class="ivo-stat-label">原料 SKU 数</span>
<span class="ivo-stat-value">42</span>
</div>
</div>
<div class="ivo-stat">
<div class="ivo-stat-icon orange"><i data-lucide="alert-triangle" style="width:20px;height:20px;"></i></div>
<div class="ivo-stat-info">
<span class="ivo-stat-label">低库存预警</span>
<span class="ivo-stat-value orange">8</span>
</div>
</div>
<div class="ivo-stat">
<div class="ivo-stat-icon red"><i data-lucide="x-circle" style="width:20px;height:20px;"></i></div>
<div class="ivo-stat-info">
<span class="ivo-stat-label">缺货原料</span>
<span class="ivo-stat-value red">2</span>
</div>
</div>
<div class="ivo-stat">
<div class="ivo-stat-icon green"><i data-lucide="wallet" style="width:20px;height:20px;"></i></div>
<div class="ivo-stat-info">
<span class="ivo-stat-label">库存总值</span>
<span class="ivo-stat-value">¥28,600</span>
</div>
</div>
</div>
<!-- 原料列表 -->
<div class="ivo-table-wrap">
<div class="ivo-table-inner">
<table class="g-table">
<thead>
<tr>
<th>原料名称</th><th>分类</th><th>单位</th><th style="text-align:right;">当前库存</th><th style="text-align:right;">安全库存</th><th style="text-align:right;">单价(元)</th><th style="text-align:right;">库存价值</th><th>状态</th><th style="width:140px;">操作</th>
</tr>
</thead>
<tbody>
<tr>
<td style="font-weight:500;">猪肉</td><td>肉类</td><td>kg</td><td style="text-align:right;">45</td><td style="text-align:right;">20</td><td style="text-align:right;">32.00</td><td style="text-align:right;">¥1,440</td><td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-warn">
<td style="font-weight:500;">鸡胸肉</td><td>肉类</td><td>kg</td><td style="text-align:right;">8</td><td style="text-align:right;">15</td><td style="text-align:right;">28.00</td><td style="text-align:right;">¥224</td><td><span class="g-tag g-tag-orange">低库存</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-danger">
<td style="font-weight:500;">牛腩</td><td>肉类</td><td>kg</td><td style="text-align:right;">0</td><td style="text-align:right;">10</td><td style="text-align:right;">65.00</td><td style="text-align:right;">¥0</td><td><span class="g-tag g-tag-red">缺货</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr>
<td style="font-weight:500;">大白菜</td><td>蔬菜</td><td>kg</td><td style="text-align:right;">30</td><td style="text-align:right;">10</td><td style="text-align:right;">4.00</td><td style="text-align:right;">¥120</td><td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr>
<td style="font-weight:500;">西红柿</td><td>蔬菜</td><td>kg</td><td style="text-align:right;">12</td><td style="text-align:right;">8</td><td style="text-align:right;">6.00</td><td style="text-align:right;">¥72</td><td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-warn">
<td style="font-weight:500;">生菜</td><td>蔬菜</td><td>kg</td><td style="text-align:right;">3</td><td style="text-align:right;">5</td><td style="text-align:right;">8.00</td><td style="text-align:right;">¥24</td><td><span class="g-tag g-tag-orange">低库存</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr>
<td style="font-weight:500;">酱油</td><td>调料</td><td></td><td style="text-align:right;">25</td><td style="text-align:right;">10</td><td style="text-align:right;">12.00</td><td style="text-align:right;">¥300</td><td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-warn">
<td style="font-weight:500;">食用油</td><td>调料</td><td></td><td style="text-align:right;">4</td><td style="text-align:right;">5</td><td style="text-align:right;">58.00</td><td style="text-align:right;">¥232</td><td><span class="g-tag g-tag-orange">低库存</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-warn">
<td style="font-weight:500;">咖啡豆</td><td>饮品原料</td><td>kg</td><td style="text-align:right;">2</td><td style="text-align:right;">5</td><td style="text-align:right;">120.00</td><td style="text-align:right;">¥240</td><td><span class="g-tag g-tag-orange">低库存</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-warn">
<td style="font-weight:500;">牛奶</td><td>饮品原料</td><td>L</td><td style="text-align:right;">15</td><td style="text-align:right;">20</td><td style="text-align:right;">8.00</td><td style="text-align:right;">¥120</td><td><span class="g-tag g-tag-orange">低库存</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr>
<td style="font-weight:500;">外卖盒</td><td>包装耗材</td><td></td><td style="text-align:right;">500</td><td style="text-align:right;">200</td><td style="text-align:right;">0.80</td><td style="text-align:right;">¥400</td><td><span class="g-tag g-tag-green">正常</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
<tr class="ivo-row-warn">
<td style="font-weight:500;">一次性筷子</td><td>包装耗材</td><td></td><td style="text-align:right;">80</td><td style="text-align:right;">100</td><td style="text-align:right;">0.30</td><td style="text-align:right;">¥24</td><td><span class="g-tag g-tag-orange">低库存</span></td>
<td><a class="g-action">编辑</a> <a class="g-action" style="margin-left:8px;">入库</a> <a class="g-action g-action-danger" style="margin-left:8px;">删除</a></td>
</tr>
</tbody>
</table>
</div>
<!-- 分页 -->
<div class="ivo-pager-bar">
<span>共 42 条</span>
<div style="display:flex;align-items:center;gap:8px;">
<select class="g-select" style="width:90px;height:28px;font-size:12px;">
<option>20 条/页</option>
<option>50 条/页</option>
<option>100 条/页</option>
</select>
<div class="g-pagination" style="margin-top:0;">
<button class="g-page-btn" disabled>&lt;</button>
<button class="g-page-btn active">1</button>
<button class="g-page-btn">2</button>
<button class="g-page-btn">3</button>
<button class="g-page-btn">&gt;</button>
</div>
</div>
</div>
</div>
</div>
<!-- 新增原料抽屉 -->
<div class="g-drawer-mask" id="ivoDrawerMask" onclick="closeIvoDrawer()"></div>
<div class="g-drawer" id="ivoDrawer" style="width:480px;">
<div class="g-drawer-hd">
<span class="g-drawer-title">新增原料</span>
<button class="g-drawer-close" onclick="closeIvoDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
</div>
<div class="g-drawer-bd">
<div class="g-form-group">
<label class="g-form-label required">原料名称</label>
<input class="g-input" placeholder="请输入原料名称" />
</div>
<div class="g-form-group">
<label class="g-form-label required">分类</label>
<select class="g-select">
<option value="">请选择分类</option>
<option>肉类</option>
<option>蔬菜</option>
<option>调料</option>
<option>饮品原料</option>
<option>包装耗材</option>
</select>
</div>
<div class="g-form-group">
<label class="g-form-label required">单位</label>
<select class="g-select">
<option value="">请选择单位</option>
<option>kg</option>
<option>g</option>
<option>L</option>
<option>ml</option>
<option></option>
<option></option>
<option></option>
<option></option>
<option></option>
</select>
</div>
<div class="g-form-group">
<label class="g-form-label required">安全库存</label>
<input class="g-input" type="number" placeholder="低于此数量将触发预警" />
</div>
<div class="g-form-group">
<label class="g-form-label required">单价</label>
<input class="g-input" type="number" placeholder="如29.90" />
</div>
<div class="g-form-group">
<label class="g-form-label">供应商</label>
<select class="g-select">
<option value="">请选择供应商</option>
<option>鲜达供应链</option>
<option>万家食材</option>
<option>优品冷链</option>
</select>
</div>
<div class="g-form-group">
<label class="g-form-label">备注</label>
<textarea class="g-textarea" rows="3" placeholder="补充说明,如存储要求、保质期等"></textarea>
</div>
</div>
<div class="g-drawer-ft">
<button class="g-btn" onclick="closeIvoDrawer()">取消</button>
<button class="g-btn g-btn-primary" onclick="closeIvoDrawer()">确认添加</button>
</div>
</div>
<script>
/* 抽屉开关 */
function openIvoDrawer() {
document.getElementById('ivoDrawerMask').classList.add('open');
document.getElementById('ivoDrawer').classList.add('open');
}
function closeIvoDrawer() {
document.getElementById('ivoDrawerMask').classList.remove('open');
document.getElementById('ivoDrawer').classList.remove('open');
}
/* 一键生成采购单 */
function ivoGenPurchase() {
var btn = document.getElementById('ivoBtnPurchase');
var orig = btn.innerHTML;
btn.innerHTML = '<i data-lucide="check" style="width:14px;height:14px;"></i> 已生成 3 条采购建议';
btn.style.borderColor = 'var(--g-success)';
btn.style.color = 'var(--g-success)';
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
setTimeout(function() {
btn.innerHTML = orig;
btn.style.borderColor = '';
btn.style.color = '';
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
}, 2000);
}
/* 初始化图标 */
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>

383
pages/inv-purchase.html Normal file
View File

@@ -0,0 +1,383 @@
<!-- 采购管理页 -->
<style>
.ivp-page { display:flex; flex-direction:column; gap:16px; font-size:13px; color:var(--g-text); }
/* 统计卡片 */
.ivp-stats { display:grid; grid-template-columns:repeat(3,1fr); gap:14px; }
.ivp-stat { background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border); padding:18px 20px; display:flex; align-items:center; gap:14px; transition:var(--g-transition); }
.ivp-stat:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
.ivp-stat-icon { width:40px; height:40px; border-radius:var(--g-radius); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.ivp-stat-icon.blue { background:hsl(212,100%,95%); color:var(--primary); }
.ivp-stat-icon.orange { background:#fff7e6; color:var(--g-warning); }
.ivp-stat-icon.green { background:#f0fdf4; color:var(--g-success); }
.ivp-stat-label { font-size:12px; color:var(--g-text-muted); margin-bottom:4px; }
.ivp-stat-value { font-size:22px; font-weight:700; color:var(--g-text); }
/* 工具栏 */
.ivp-toolbar { display:flex; align-items:center; gap:12px; background:#fff; border-radius:10px; padding:12px 16px; box-shadow:var(--g-shadow-sm); flex-wrap:wrap; }
.ivp-toolbar .ivp-right { margin-left:auto; display:flex; gap:8px; }
/* 表格容器 */
.ivp-table-wrap { background:#fff; border-radius:10px; box-shadow:var(--g-shadow-sm); overflow:hidden; }
/* 供应商卡片网格 */
.ivp-vendor-grid { display:grid; grid-template-columns:repeat(2,1fr); gap:14px; }
.ivp-vendor-card { background:#fff; border-radius:var(--g-radius); border:1px solid var(--g-border); padding:20px; transition:var(--g-transition); }
.ivp-vendor-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
.ivp-vendor-hd { display:flex; align-items:center; justify-content:space-between; margin-bottom:12px; }
.ivp-vendor-name { font-size:15px; font-weight:600; color:var(--g-text); }
.ivp-vendor-info { display:grid; grid-template-columns:1fr 1fr; gap:8px 20px; font-size:13px; color:var(--g-text-secondary); margin-bottom:12px; }
.ivp-vendor-info span { display:flex; align-items:center; gap:6px; }
.ivp-vendor-info i { width:14px; height:14px; color:var(--g-text-muted); }
.ivp-vendor-ft { display:flex; align-items:center; justify-content:space-between; padding-top:12px; border-top:1px solid var(--g-border); }
/* 星星评分 */
.ivp-stars { display:flex; gap:2px; }
.ivp-star { width:16px; height:16px; position:relative; }
.ivp-star-bg { color:#e5e7eb; }
.ivp-star-fg { color:#facc15; position:absolute; top:0; left:0; overflow:hidden; }
/* 采购明细行 */
.ivp-detail-row { display:flex; gap:8px; align-items:center; margin-bottom:10px; }
.ivp-detail-row .g-select, .ivp-detail-row .g-input { flex:1; }
.ivp-detail-row .ivp-qty { width:90px; flex:none; }
.ivp-detail-row .ivp-price { width:100px; flex:none; }
.ivp-del-btn { width:32px; height:32px; border:none; background:none; color:var(--g-text-muted); cursor:pointer; border-radius:var(--g-radius-sm); transition:var(--g-transition); display:flex; align-items:center; justify-content:center; flex-shrink:0; }
.ivp-del-btn:hover { color:var(--g-danger); background:#fef2f2; }
.ivp-add-row { display:flex; align-items:center; gap:6px; color:var(--primary); font-size:13px; cursor:pointer; padding:6px 0; border:none; background:none; transition:var(--g-transition); }
.ivp-add-row:hover { opacity:.8; }
</style>
<div class="ivp-page">
<!-- 分段切换 -->
<div class="g-seg" style="width:240px;">
<div class="g-seg-item active" onclick="switchIvpTab(this,'orders')">采购单</div>
<div class="g-seg-item" onclick="switchIvpTab(this,'vendors')">供应商</div>
</div>
<!-- ========== Tab1: 采购单 ========== -->
<div id="ivpTabOrders">
<!-- 统计卡片 -->
<div class="ivp-stats" style="margin-bottom:16px;">
<div class="ivp-stat">
<div class="ivp-stat-icon blue"><i data-lucide="wallet" style="width:20px;height:20px;"></i></div>
<div><div class="ivp-stat-label">本月采购额</div><div class="ivp-stat-value" style="color:var(--primary);">&#165;18,500</div></div>
</div>
<div class="ivp-stat">
<div class="ivp-stat-icon orange"><i data-lucide="clock" style="width:20px;height:20px;"></i></div>
<div><div class="ivp-stat-label">待审核</div><div class="ivp-stat-value" style="color:var(--g-warning);">3<span style="font-size:13px;font-weight:400;color:var(--g-text-muted);margin-left:4px;"></span></div></div>
</div>
<div class="ivp-stat">
<div class="ivp-stat-icon green"><i data-lucide="truck" style="width:20px;height:20px;"></i></div>
<div><div class="ivp-stat-label">待到货</div><div class="ivp-stat-value" style="color:var(--g-success);">2<span style="font-size:13px;font-weight:400;color:var(--g-text-muted);margin-left:4px;"></span></div></div>
</div>
</div>
<!-- 工具栏 -->
<div class="ivp-toolbar" style="margin-bottom:16px;">
<input class="g-input" type="date" value="2026-02-01" style="width:140px;">
<span style="color:var(--g-text-muted);"></span>
<input class="g-input" type="date" value="2026-02-12" style="width:140px;">
<select class="g-select" style="width:130px;">
<option>全部状态</option>
<option>待审核</option>
<option>已下单</option>
<option>已到货</option>
<option>已取消</option>
</select>
<div class="ivp-right">
<button class="g-btn g-btn-primary" onclick="openIvpDrawer()"><i data-lucide="plus" style="width:15px;height:15px;"></i> 新建采购单</button>
</div>
</div>
<!-- 表格 -->
<div class="ivp-table-wrap">
<table class="g-table">
<thead>
<tr>
<th>采购单号</th>
<th>创建日期</th>
<th>供应商</th>
<th>采购项数</th>
<th>总金额</th>
<th>状态</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<tr>
<td style="font-weight:500;">PO20260201001</td>
<td>2026-02-01</td>
<td>鑫源肉业</td>
<td>5</td>
<td style="font-weight:600;">&#165;4,200.00</td>
<td><span class="g-tag g-tag-orange">待审核</span></td>
<td><a class="g-action">查看</a><a class="g-action">确认到货</a><a class="g-action-danger">取消</a></td>
</tr>
<tr>
<td style="font-weight:500;">PO20260203002</td>
<td>2026-02-03</td>
<td>绿田蔬菜批发</td>
<td>8</td>
<td style="font-weight:600;">&#165;1,860.00</td>
<td><span class="g-tag g-tag-blue">已下单</span></td>
<td><a class="g-action">查看</a><a class="g-action">确认到货</a><a class="g-action-danger">取消</a></td>
</tr>
<tr>
<td style="font-weight:500;">PO20260205003</td>
<td>2026-02-05</td>
<td>味达调料商行</td>
<td>3</td>
<td style="font-weight:600;">&#165;920.00</td>
<td><span class="g-tag g-tag-green">已到货</span></td>
<td><a class="g-action">查看</a></td>
</tr>
<tr>
<td style="font-weight:500;">PO20260206004</td>
<td>2026-02-06</td>
<td>鑫源肉业</td>
<td>4</td>
<td style="font-weight:600;">&#165;5,300.00</td>
<td><span class="g-tag g-tag-orange">待审核</span></td>
<td><a class="g-action">查看</a><a class="g-action">确认到货</a><a class="g-action-danger">取消</a></td>
</tr>
<tr>
<td style="font-weight:500;">PO20260208005</td>
<td>2026-02-08</td>
<td>优品包装</td>
<td>6</td>
<td style="font-weight:600;">&#165;3,480.00</td>
<td><span class="g-tag g-tag-blue">已下单</span></td>
<td><a class="g-action">查看</a><a class="g-action">确认到货</a><a class="g-action-danger">取消</a></td>
</tr>
<tr>
<td style="font-weight:500;">PO20260210006</td>
<td>2026-02-10</td>
<td>绿田蔬菜批发</td>
<td>2</td>
<td style="font-weight:600;">&#165;640.00</td>
<td><span class="g-tag g-tag-gray">已取消</span></td>
<td><a class="g-action">查看</a></td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- ========== Tab2: 供应商 ========== -->
<div id="ivpTabVendors" style="display:none;">
<!-- 工具栏 -->
<div class="ivp-toolbar" style="margin-bottom:16px;">
<div style="position:relative;">
<i data-lucide="search" style="width:15px;height:15px;position:absolute;left:10px;top:50%;transform:translateY(-50%);color:var(--g-text-muted);"></i>
<input class="g-input" placeholder="搜索供应商名称" style="width:200px;padding-left:32px;">
</div>
<select class="g-select" style="width:130px;">
<option>全部分类</option>
<option>肉类</option>
<option>蔬菜</option>
<option>调料</option>
<option>饮品</option>
<option>包装</option>
</select>
<div class="ivp-right">
<button class="g-btn g-btn-primary"><i data-lucide="plus" style="width:15px;height:15px;"></i> 新增供应商</button>
</div>
</div>
<!-- 供应商卡片 -->
<div class="ivp-vendor-grid">
<!-- 鑫源肉业 -->
<div class="ivp-vendor-card">
<div class="ivp-vendor-hd">
<div class="ivp-vendor-name">鑫源肉业</div>
<span class="g-tag g-tag-red">肉类</span>
</div>
<div class="ivp-vendor-info">
<span><i data-lucide="user"></i> 张经理</span>
<span><i data-lucide="phone"></i> 138-0001-2345</span>
<span><i data-lucide="calendar"></i> 合作 2 年</span>
<span><i data-lucide="wallet"></i> 累计 &#165;86,000</span>
</div>
<div class="ivp-vendor-ft">
<div class="ivp-stars" data-score="4.5"></div>
<div><a class="g-action">编辑</a><a class="g-action">查看采购记录</a></div>
</div>
</div>
<!-- 绿田蔬菜批发 -->
<div class="ivp-vendor-card">
<div class="ivp-vendor-hd">
<div class="ivp-vendor-name">绿田蔬菜批发</div>
<span class="g-tag g-tag-green">蔬菜</span>
</div>
<div class="ivp-vendor-info">
<span><i data-lucide="user"></i> 李老板</span>
<span><i data-lucide="phone"></i> 139-8877-6543</span>
<span><i data-lucide="calendar"></i> 合作 3 年</span>
<span><i data-lucide="wallet"></i> 累计 &#165;124,500</span>
</div>
<div class="ivp-vendor-ft">
<div class="ivp-stars" data-score="4.8"></div>
<div><a class="g-action">编辑</a><a class="g-action">查看采购记录</a></div>
</div>
</div>
<!-- 味达调料商行 -->
<div class="ivp-vendor-card">
<div class="ivp-vendor-hd">
<div class="ivp-vendor-name">味达调料商行</div>
<span class="g-tag g-tag-orange">调料</span>
</div>
<div class="ivp-vendor-info">
<span><i data-lucide="user"></i> 王师傅</span>
<span><i data-lucide="phone"></i> 136-5544-3210</span>
<span><i data-lucide="calendar"></i> 合作 1 年</span>
<span><i data-lucide="wallet"></i> 累计 &#165;32,800</span>
</div>
<div class="ivp-vendor-ft">
<div class="ivp-stars" data-score="4.2"></div>
<div><a class="g-action">编辑</a><a class="g-action">查看采购记录</a></div>
</div>
</div>
<!-- 优品包装 -->
<div class="ivp-vendor-card">
<div class="ivp-vendor-hd">
<div class="ivp-vendor-name">优品包装</div>
<span class="g-tag g-tag-gray">包装耗材</span>
</div>
<div class="ivp-vendor-info">
<span><i data-lucide="user"></i> 陈总</span>
<span><i data-lucide="phone"></i> 137-2233-4455</span>
<span><i data-lucide="calendar"></i> 合作 1.5 年</span>
<span><i data-lucide="wallet"></i> 累计 &#165;18,200</span>
</div>
<div class="ivp-vendor-ft">
<div class="ivp-stars" data-score="4.0"></div>
<div><a class="g-action">编辑</a><a class="g-action">查看采购记录</a></div>
</div>
</div>
</div>
</div>
</div>
<!-- ========== 新建采购单抽屉 ========== -->
<div class="g-drawer-mask" id="ivpDrawerMask" onclick="closeIvpDrawer()"></div>
<div class="g-drawer" id="ivpDrawer" style="width:520px;">
<div class="g-drawer-hd">
<div class="g-drawer-title">新建采购单</div>
<button class="g-drawer-close" onclick="closeIvpDrawer()"><i data-lucide="x" style="width:18px;height:18px;"></i></button>
</div>
<div class="g-drawer-bd">
<div class="g-form-group">
<label class="g-form-label required">供应商</label>
<select class="g-select">
<option value="">请选择供应商</option>
<option>鑫源肉业</option>
<option>绿田蔬菜批发</option>
<option>味达调料商行</option>
<option>优品包装</option>
</select>
</div>
<div class="g-form-group">
<label class="g-form-label">预计到货日期</label>
<input class="g-input" type="date" value="2026-02-15">
</div>
<div class="g-form-group">
<label class="g-form-label required">采购明细</label>
<div id="ivpDetailList">
<div class="ivp-detail-row">
<select class="g-select"><option>鸡胸肉</option><option>牛腩</option><option>五花肉</option><option>牛奶</option><option>咖啡豆</option><option>生菜</option><option>番茄</option></select>
<input class="g-input ivp-qty" type="number" value="20" placeholder="数量">
<span style="color:var(--g-text-muted);flex-shrink:0;">kg</span>
<input class="g-input ivp-price" type="number" value="35.00" placeholder="单价">
<button class="ivp-del-btn" onclick="removeIvpRow(this)"><i data-lucide="trash-2" style="width:15px;height:15px;"></i></button>
</div>
<div class="ivp-detail-row">
<select class="g-select"><option>牛奶</option><option>鸡胸肉</option><option>牛腩</option><option>五花肉</option><option>咖啡豆</option><option>生菜</option><option>番茄</option></select>
<input class="g-input ivp-qty" type="number" value="30" placeholder="数量">
<span style="color:var(--g-text-muted);flex-shrink:0;">L</span>
<input class="g-input ivp-price" type="number" value="8.50" placeholder="单价">
<button class="ivp-del-btn" onclick="removeIvpRow(this)"><i data-lucide="trash-2" style="width:15px;height:15px;"></i></button>
</div>
<div class="ivp-detail-row">
<select class="g-select"><option>咖啡豆</option><option>鸡胸肉</option><option>牛腩</option><option>五花肉</option><option>牛奶</option><option>生菜</option><option>番茄</option></select>
<input class="g-input ivp-qty" type="number" value="5" placeholder="数量">
<span style="color:var(--g-text-muted);flex-shrink:0;">kg</span>
<input class="g-input ivp-price" type="number" value="120.00" placeholder="单价">
<button class="ivp-del-btn" onclick="removeIvpRow(this)"><i data-lucide="trash-2" style="width:15px;height:15px;"></i></button>
</div>
</div>
<button class="ivp-add-row" onclick="addIvpRow()"><i data-lucide="plus-circle" style="width:15px;height:15px;"></i> 添加原料</button>
</div>
<div class="g-form-group">
<label class="g-form-label">备注</label>
<textarea class="g-textarea" rows="3" placeholder="请输入备注信息,如特殊包装要求、配送时间等"></textarea>
</div>
</div>
<div class="g-drawer-ft">
<button class="g-btn" onclick="closeIvpDrawer()">取消</button>
<button class="g-btn g-btn-primary" onclick="closeIvpDrawer()">提交采购单</button>
</div>
</div>
<script>
/* Tab 切换 */
function switchIvpTab(el, tab) {
el.parentElement.querySelectorAll('.g-seg-item').forEach(function(s){ s.classList.remove('active'); });
el.classList.add('active');
document.getElementById('ivpTabOrders').style.display = tab === 'orders' ? '' : 'none';
document.getElementById('ivpTabVendors').style.display = tab === 'vendors' ? '' : 'none';
if (typeof lucide !== 'undefined') lucide.createIcons();
}
/* 抽屉 */
function openIvpDrawer() {
document.getElementById('ivpDrawerMask').classList.add('open');
document.getElementById('ivpDrawer').classList.add('open');
if (typeof lucide !== 'undefined') lucide.createIcons();
}
function closeIvpDrawer() {
document.getElementById('ivpDrawerMask').classList.remove('open');
document.getElementById('ivpDrawer').classList.remove('open');
}
/* 采购明细行 */
function addIvpRow() {
var list = document.getElementById('ivpDetailList');
var row = document.createElement('div');
row.className = 'ivp-detail-row';
row.innerHTML = '<select class="g-select"><option value="">请选择原料</option><option>鸡胸肉</option><option>牛腩</option><option>五花肉</option><option>牛奶</option><option>咖啡豆</option><option>生菜</option><option>番茄</option></select>'
+ '<input class="g-input ivp-qty" type="number" placeholder="数量">'
+ '<span style="color:var(--g-text-muted);flex-shrink:0;">kg</span>'
+ '<input class="g-input ivp-price" type="number" placeholder="单价">'
+ '<button class="ivp-del-btn" onclick="removeIvpRow(this)"><i data-lucide="trash-2" style="width:15px;height:15px;"></i></button>';
list.appendChild(row);
if (typeof lucide !== 'undefined') lucide.createIcons();
}
function removeIvpRow(btn) {
var row = btn.closest('.ivp-detail-row');
if (document.querySelectorAll('.ivp-detail-row').length > 1) {
row.remove();
}
}
/* 星星评分渲染 */
function renderIvpStars() {
document.querySelectorAll('.ivp-stars[data-score]').forEach(function(wrap) {
var score = parseFloat(wrap.getAttribute('data-score'));
var html = '';
for (var i = 1; i <= 5; i++) {
var pct = Math.min(100, Math.max(0, (score - i + 1) * 100));
html += '<div class="ivp-star">'
+ '<i data-lucide="star" class="ivp-star-bg" style="width:16px;height:16px;fill:#e5e7eb;stroke:none;"></i>'
+ '<div class="ivp-star-fg" style="width:' + pct + '%;">'
+ '<i data-lucide="star" style="width:16px;height:16px;fill:#facc15;stroke:none;"></i>'
+ '</div></div>';
}
html += '<span style="font-size:12px;color:var(--g-text-secondary);margin-left:6px;">' + score.toFixed(1) + '</span>';
wrap.innerHTML = html;
});
}
renderIvpStars();
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>

250
pages/inv-soldout.html Normal file
View File

@@ -0,0 +1,250 @@
<!-- 估清管理页 -->
<style>
.ivs-page { max-width:1000px; display:flex; flex-direction:column; gap:16px; font-size:13px; color:var(--g-text); }
/* 顶部自动估清卡片 */
.ivs-auto-card { display:flex; align-items:center; gap:16px; flex-wrap:wrap; }
.ivs-auto-left { flex:1; min-width:200px; }
.ivs-auto-title { font-size:15px; font-weight:600; color:var(--g-text); margin-bottom:4px; }
.ivs-auto-desc { font-size:12px; color:var(--g-text-secondary); }
.ivs-auto-hint { font-size:12px; color:var(--g-text-muted); margin-top:12px; width:100%; padding-top:10px; border-top:1px solid var(--g-border); display:flex; align-items:center; gap:4px; }
/* 统计卡片 */
.ivs-stats { display:grid; grid-template-columns:repeat(3,1fr); gap:14px; }
.ivs-stat-card { background:#fff; border-radius:var(--g-radius); padding:18px 20px; box-shadow:var(--g-shadow-sm); border:1px solid var(--g-border); transition:var(--g-transition); }
.ivs-stat-card:hover { box-shadow:var(--g-shadow-md); transform:translateY(-1px); }
.ivs-stat-label { font-size:12px; color:var(--g-text-muted); margin-bottom:8px; display:flex; align-items:center; gap:6px; }
.ivs-stat-label i { width:14px; height:14px; }
.ivs-stat-value { font-size:28px; font-weight:700; color:var(--g-text); }
.ivs-stat-value span { font-size:13px; font-weight:400; color:var(--g-text-secondary); margin-left:2px; }
.ivs-stat-sub { font-size:11px; color:var(--g-text-muted); margin-top:4px; }
.ivs-stat-card.danger .ivs-stat-value { color:var(--g-danger); }
.ivs-stat-card.warning .ivs-stat-value { color:var(--g-warning); }
/* Section 标题 */
.ivs-section-hd { font-size:15px; font-weight:600; color:var(--g-text); padding-left:10px; border-left:3px solid var(--primary); margin-bottom:16px; }
/* 表格微调 */
.ivs-page .g-table { font-size:13px; }
.ivs-page .g-table th { background:#f8f9fb; }
.ivs-page .g-table td { vertical-align:middle; }
.ivs-dishes { display:flex; flex-wrap:wrap; gap:4px; }
.ivs-dish-tag { background:color-mix(in srgb, var(--primary) 8%, #fff); color:var(--primary); font-size:11px; padding:2px 8px; border-radius:10px; white-space:nowrap; }
.ivs-more-tag { background:#f3f4f6; color:var(--g-text-muted); font-size:11px; padding:2px 8px; border-radius:10px; cursor:pointer; }
/* 手动估清操作区 */
.ivs-manual-bar { display:flex; align-items:center; gap:10px; flex-wrap:wrap; }
.ivs-manual-bar select { height:36px; padding:0 12px; border:1px solid #e5e7eb; border-radius:var(--g-radius-sm); font-size:13px; outline:none; min-width:240px; transition:var(--g-transition); }
.ivs-manual-bar select:focus { border-color:var(--primary); box-shadow:0 0 0 3px color-mix(in srgb, var(--primary) 12%, transparent); }
.ivs-section-desc { font-size:12px; color:var(--g-text-muted); margin-bottom:14px; display:flex; align-items:center; gap:4px; }
.ivs-section-desc i { width:14px; height:14px; }
</style>
<div class="ivs-page">
<!-- 顶部:自动估清开关 -->
<div class="g-card" style="padding:18px 20px;">
<div class="ivs-auto-card">
<div class="ivs-auto-left">
<div class="ivs-auto-title">自动估清</div>
<div class="ivs-auto-desc">当原料库存为 0 时,自动将关联菜品标记为售罄</div>
</div>
<div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div>
</div>
<div class="ivs-auto-hint"><i data-lucide="link" style="width:13px;height:13px;"></i>已关联 28 个原料 &rarr; 56 道菜品</div>
</div>
<!-- 统计卡片 -->
<div class="ivs-stats">
<div class="ivs-stat-card danger">
<div class="ivs-stat-label"><i data-lucide="ban"></i>当前售罄菜品</div>
<div class="ivs-stat-value">3<span></span></div>
<div class="ivs-stat-sub">其中自动估清 2 道</div>
</div>
<div class="ivs-stat-card warning">
<div class="ivs-stat-label"><i data-lucide="alert-triangle"></i>低库存预警菜品</div>
<div class="ivs-stat-value">5<span></span></div>
<div class="ivs-stat-sub">原料即将耗尽</div>
</div>
<div class="ivs-stat-card">
<div class="ivs-stat-label"><i data-lucide="hand"></i>今日手动估清</div>
<div class="ivs-stat-value">1<span></span></div>
<div class="ivs-stat-sub">操作人:张经理</div>
</div>
</div>
<!-- Section 1: 当前已估清菜品 -->
<div class="g-card" style="padding:18px 20px;">
<div class="ivs-section-hd">当前已估清菜品</div>
<table class="g-table">
<thead><tr><th>菜品名称</th><th>估清原因</th><th>关联原料</th><th>原料库存</th><th>估清时间</th><th style="width:80px;">操作</th></tr></thead>
<tbody>
<tr>
<td style="font-weight:500;">红烧牛腩</td>
<td><span class="g-tag g-tag-orange">自动</span></td>
<td>牛腩</td>
<td><span style="color:var(--g-danger);font-weight:600;">0 kg</span></td>
<td>2026-02-12 09:15</td>
<td><span class="g-action" onclick="alert('已恢复上架')">恢复上架</span></td>
</tr>
<tr>
<td style="font-weight:500;">鸡胸肉沙拉</td>
<td><span class="g-tag g-tag-orange">自动</span></td>
<td>鸡胸肉</td>
<td><span style="color:var(--g-warning);font-weight:600;">0.3 kg</span></td>
<td>2026-02-12 10:30</td>
<td><span class="g-action" onclick="alert('已恢复上架')">恢复上架</span></td>
</tr>
<tr>
<td style="font-weight:500;">芒果冰沙</td>
<td><span class="g-tag g-tag-blue">手动</span></td>
<td></td>
<td></td>
<td>2026-02-12 11:00</td>
<td><span class="g-action" onclick="alert('已恢复上架')">恢复上架</span></td>
</tr>
<tr>
<td style="font-weight:500;">牛肉汉堡</td>
<td><span class="g-tag g-tag-orange">自动</span></td>
<td>牛腩</td>
<td><span style="color:var(--g-danger);font-weight:600;">0 kg</span></td>
<td>2026-02-12 09:15</td>
<td><span class="g-action" onclick="alert('已恢复上架')">恢复上架</span></td>
</tr>
</tbody>
</table>
</div>
<!-- Section 2: 原料→菜品关联映射 -->
<div class="g-card" style="padding:18px 20px;">
<div class="ivs-section-hd">原料 &rarr; 菜品关联映射</div>
<div class="ivs-section-desc"><i data-lucide="info"></i>设置原料与菜品的关联关系,当原料库存归零时自动估清关联菜品</div>
<table class="g-table">
<thead><tr><th>原料名称</th><th>当前库存</th><th>安全库存</th><th>关联菜品数</th><th>关联菜品</th><th style="width:80px;">自动估清</th></tr></thead>
<tbody>
<tr>
<td style="font-weight:500;">牛腩</td>
<td><span style="color:var(--g-danger);font-weight:600;">0 kg</span></td>
<td>5 kg</td>
<td>3</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">红烧牛腩</span><span class="ivs-dish-tag">牛肉汉堡</span><span class="ivs-more-tag">+1</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">鸡胸肉</td>
<td><span style="color:var(--g-warning);font-weight:600;">0.3 kg</span></td>
<td>3 kg</td>
<td>2</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">鸡胸肉沙拉</span><span class="ivs-dish-tag">照烧鸡排饭</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">三文鱼</td>
<td>2.5 kg</td>
<td>2 kg</td>
<td>2</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">三文鱼刺身</span><span class="ivs-dish-tag">三文鱼寿司</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">芒果</td>
<td>8 个</td>
<td>5 个</td>
<td>3</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">芒果冰沙</span><span class="ivs-dish-tag">杨枝甘露</span><span class="ivs-more-tag">+1</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">虾仁</td>
<td>1.2 kg</td>
<td>2 kg</td>
<td>4</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">虾仁炒饭</span><span class="ivs-dish-tag">鲜虾云吞</span><span class="ivs-more-tag">+2</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">豆腐</td>
<td>15 块</td>
<td>10 块</td>
<td>2</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">麻婆豆腐</span><span class="ivs-dish-tag">皮蛋豆腐</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">培根</td>
<td>3 kg</td>
<td>2 kg</td>
<td>3</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">培根披萨</span><span class="ivs-dish-tag">培根意面</span><span class="ivs-more-tag">+1</span></div></td>
<td><div class="g-toggle" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
<tr>
<td style="font-weight:500;">鳗鱼</td>
<td>1 kg</td>
<td>1.5 kg</td>
<td>1</td>
<td><div class="ivs-dishes"><span class="ivs-dish-tag">鳗鱼饭</span></div></td>
<td><div class="g-toggle on" onclick="toggleSwitch(this)"><div class="g-toggle-dot"></div></div></td>
</tr>
</tbody>
</table>
</div>
<!-- Section 3: 手动估清 -->
<div class="g-card" style="padding:18px 20px;">
<div class="ivs-section-hd">手动估清</div>
<div class="ivs-manual-bar" style="margin-bottom:16px;">
<select>
<option value="">请选择要估清的菜品...</option>
<option>宫保鸡丁</option>
<option>鱼香肉丝</option>
<option>水煮牛肉</option>
<option>糖醋排骨</option>
<option>蒜蓉西兰花</option>
<option>番茄鸡蛋汤</option>
</select>
<button class="g-btn g-btn-primary g-btn-sm" onclick="handleManualSoldout()"><i data-lucide="x-circle" style="width:14px;height:14px;margin-right:4px;vertical-align:-2px;"></i>标记售罄</button>
</div>
<div style="font-size:12px;color:var(--g-text-muted);margin-bottom:10px;">今日手动估清记录</div>
<table class="g-table">
<thead><tr><th>菜品</th><th>操作人</th><th>时间</th><th style="width:80px;">操作</th></tr></thead>
<tbody id="manualRecords">
<tr>
<td style="font-weight:500;">芒果冰沙</td>
<td>张经理</td>
<td>2026-02-12 11:00</td>
<td><span class="g-action" onclick="alert('已恢复上架')">恢复</span></td>
</tr>
</tbody>
</table>
</div>
</div>
<script>
function toggleSwitch(el) {
el.classList.toggle('on');
}
function handleManualSoldout() {
var sel = document.querySelector('.ivs-manual-bar select');
var name = sel.value;
if (!name) { alert('请先选择菜品'); return; }
var tbody = document.getElementById('manualRecords');
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');
var tr = document.createElement('tr');
tr.innerHTML = '<td style="font-weight:500;">' + name + '</td><td>当前用户</td><td>' + ts + '</td><td><span class="g-action" onclick="alert(\'已恢复上架\')">恢复</span></td>';
tbody.insertBefore(tr, tbody.firstChild);
sel.value = '';
alert('已将「' + name + '」标记为售罄');
}
if (typeof lucide !== 'undefined') { lucide.createIcons(); }
</script>