feat: 营养用餐模块多页面交互优化(数据分析/模型管理/终端/餐线)
- din-data-nutri: 新增食堂切换栏、周选择器、餐品明细弹窗重构、二级弹窗表单样式 - din-data-benefit: 新增食堂切换栏、食材分类级联选择器、重置按钮,移除损耗原因列 - din-model-llm: 新增 API_KEY/API_URL 列,状态改为启用/停用,新增接入/编辑模型弹窗 - din-model-small: 新增「新增模型」弹窗 - din-terminal: 新增食堂切换栏,筛选栏/表格列精简,新增设备弹窗字段调整 - din-order-line: 三个 Tab 操作列移除「编辑」链接,仅保留「详情」
This commit is contained in:
@@ -117,6 +117,15 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.loss-bar__fill{height:100%;border-radius:9px;transition:width .4s;}
|
||||
.loss-bar__val{width:60px;font-weight:500;}
|
||||
.loss-tip{background:#FFF7E6;border:1px solid #FFE58F;border-radius:var(--radius-sm);padding:10px 14px;font-size:var(--font-sm);color:#D48806;margin-top:12px;display:flex;align-items:flex-start;gap:6px;}
|
||||
/* 页面信息栏 */
|
||||
.page-header-bar{display:flex;align-items:center;justify-content:space-between;background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);}
|
||||
.page-header-bar__left{display:flex;align-items:center;gap:12px;}
|
||||
.page-header-bar__title{font-size:var(--font-lg);font-weight:700;color:var(--text-primary);}
|
||||
.page-header-bar__meta{font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
.page-header-bar__right{display:flex;align-items:center;gap:12px;}
|
||||
.page-header-bar__right label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.page-header-bar__right .canteen-select{height:36px;border:2px solid var(--primary);border-radius:var(--radius-sm);padding:0 32px 0 14px;font-size:var(--font-sm);color:var(--primary);font-weight:500;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='%231890FF'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;min-width:140px;}
|
||||
|
||||
/* 食材成本明细弹窗 */
|
||||
.cost-header{display:flex;gap:24px;margin-bottom:16px;font-size:var(--font-sm);}
|
||||
.cost-header span{color:var(--text-secondary);}
|
||||
@@ -129,6 +138,21 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.cost-summary{display:flex;justify-content:flex-end;gap:24px;padding:12px 16px;background:#FAFAFA;border-radius:0 0 var(--radius-md) var(--radius-md);font-size:var(--font-sm);}
|
||||
.cost-summary span{color:var(--text-secondary);}
|
||||
.cost-summary strong{color:var(--primary);margin-left:4px;}
|
||||
/* 级联选择器 */
|
||||
.cascade-picker{position:relative;}
|
||||
.cascade-trigger{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 28px 0 12px;font-size:var(--font-sm);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;cursor:pointer;display:flex;align-items:center;white-space:nowrap;color:var(--text-placeholder);min-width:120px;}
|
||||
.cascade-trigger.has-value{color:var(--text-primary);}
|
||||
.cascade-panel{display:none;position:fixed;z-index:200;background:#fff;border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-md);width:320px;}
|
||||
.cascade-panel.show{display:flex;}
|
||||
.cascade-col{width:50%;max-height:240px;overflow-y:auto;}
|
||||
.cascade-col+.cascade-col{border-left:1px solid #f0f0f0;}
|
||||
.cascade-col__title{font-size:var(--font-xs);color:var(--text-placeholder);padding:8px 12px;border-bottom:1px solid #f0f0f0;position:sticky;top:0;background:#fff;}
|
||||
.cascade-opt{padding:7px 12px;font-size:var(--font-xs);cursor:pointer;transition:background .15s;display:flex;align-items:center;justify-content:space-between;}
|
||||
.cascade-opt:hover{background:#F8FBFF;}
|
||||
.cascade-opt.active{background:var(--primary-light);color:var(--primary);font-weight:500;}
|
||||
.cascade-opt .arrow-r{font-size:10px;color:var(--text-placeholder);}
|
||||
/* 重置按钮 */
|
||||
.btn-reset{background:#fff;color:var(--text-secondary);border:1px solid var(--border);}.btn-reset:hover{color:var(--danger);border-color:var(--danger);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -196,9 +220,25 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
|
||||
<!-- 主内容 -->
|
||||
<main class="main">
|
||||
<!-- 页面信息栏 -->
|
||||
<div class="page-header-bar">
|
||||
<div class="page-header-bar__left">
|
||||
<span class="page-header-bar__title">食材效益</span>
|
||||
<span class="page-header-bar__meta">2026-05-20 · 数据实时更新</span>
|
||||
</div>
|
||||
<div class="page-header-bar__right">
|
||||
<label>当前食堂</label>
|
||||
<select class="canteen-select" id="globalCanteen">
|
||||
<option value="1">一食堂(东区)</option>
|
||||
<option value="2">二食堂(西区)</option>
|
||||
<option value="3">三食堂(北区)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="stats-row">
|
||||
<div class="stat-card"><div class="stat-card__icon blue">📅</div><div class="stat-card__info"><div class="stat-card__value">2026-04</div><div class="stat-card__label">统计周期</div></div></div>
|
||||
<div class="stat-card"><div class="stat-card__icon blue">📅</div><div class="stat-card__info"><div class="stat-card__value">2026-05</div><div class="stat-card__label">统计周期</div></div></div>
|
||||
<div class="stat-card"><div class="stat-card__icon blue">💰</div><div class="stat-card__info"><div class="stat-card__value">¥26.4万</div><div class="stat-card__label">餐材总采购金额</div></div></div>
|
||||
<div class="stat-card"><div class="stat-card__icon green">📈</div><div class="stat-card__info"><div class="stat-card__value">¥12.6万</div><div class="stat-card__label">毛利总额</div></div></div>
|
||||
<div class="stat-card"><div class="stat-card__icon orange">🗑️</div><div class="stat-card__info"><div class="stat-card__value">¥1.5万</div><div class="stat-card__label">损耗金额</div></div></div>
|
||||
@@ -217,11 +257,20 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>统计开始日期</label><input class="filter-input" type="date"></div>
|
||||
<div class="filter-item"><label>统计结束日期</label><input class="filter-input" type="date"></div>
|
||||
<div class="filter-item"><label>食材分类</label><select class="filter-select"><option>全部</option><option>蔬菜类</option><option>肉禽类</option><option>水产类</option></select></div>
|
||||
<div class="filter-item"><label>食材分类</label>
|
||||
<div class="cascade-picker" id="benefitCategoryPicker">
|
||||
<div class="cascade-trigger" id="benefitCascadeTrigger" onclick="toggleBenefitCascade()">全部</div>
|
||||
<div class="cascade-panel" id="benefitCascadePanel">
|
||||
<div class="cascade-col" id="benefitCascadeL1"></div>
|
||||
<div class="cascade-col" id="benefitCascadeL2"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="filter-item"><label>供应商</label><select class="filter-select"><option>全部</option><option>绿源农业</option><option>旺旺肉业</option><option>东海水产</option></select></div>
|
||||
<div class="filter-item"><label>损耗率区间</label><select class="filter-select"><option>全部</option><option><5%</option><option>5%-10%</option><option>>10%</option></select></div>
|
||||
<div class="filter-item"><label>预警等级</label><select class="filter-select"><option>全部</option><option>低</option><option>中</option><option>高</option></select></div>
|
||||
<button class="btn btn-primary">🔍 查询</button>
|
||||
<button class="btn btn-reset" onclick="resetFilter(0)">↻ 重置</button>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-primary"><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>
|
||||
@@ -233,14 +282,14 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>统计日期</th><th>食材编号</th><th>食材名称</th><th>所属分类</th><th>供应商</th><th>采购量(kg)</th><th>采购单价(元/kg)</th><th>采购总金额</th><th>实际使用量(kg)</th><th>损耗量(kg)</th><th>损耗金额</th><th>损耗率</th><th>预警等级</th><th>损耗原因</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>统计日期</th><th>食材编号</th><th>食材名称</th><th>所属分类</th><th>供应商</th><th>采购量(kg)</th><th>采购单价(元/kg)</th><th>采购总金额</th><th>实际使用量(kg)</th><th>损耗量(kg)</th><th>损耗金额</th><th>损耗率</th><th>预警等级</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>2026-04-22</td><td>ING-001</td><td>大白菜</td><td>蔬菜类</td><td>绿源农业</td><td>620</td><td>¥1.8</td><td>¥1,116</td><td>605</td><td>15</td><td>¥27</td><td><span class="tag tag-green">2.4%</span></td><td><span class="tag tag-green">低</span></td><td>加工损耗</td><td class="td-actions"><a class="link">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-22</td><td>ING-002</td><td>菠菜</td><td>蔬菜类</td><td>绿源农业</td><td>380</td><td>¥2.5</td><td>¥950</td><td>345</td><td>35</td><td>¥87.5</td><td><span class="tag tag-orange">9.2%</span></td><td><span class="tag tag-orange">中</span></td><td>储存变质</td><td class="td-actions"><a class="link">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-21</td><td>ING-003</td><td>猪肉(五花)</td><td>肉禽类</td><td>旺旺肉业</td><td>480</td><td>¥26</td><td>¥12,480</td><td>462</td><td>18</td><td>¥468</td><td><span class="tag tag-green">3.8%</span></td><td><span class="tag tag-green">低</span></td><td>加工损耗</td><td class="td-actions"><a class="link">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-21</td><td>ING-004</td><td>鸡胸肉</td><td>肉禽类</td><td>旺旺肉业</td><td>320</td><td>¥20</td><td>¥6,400</td><td>308</td><td>12</td><td>¥240</td><td><span class="tag tag-green">3.8%</span></td><td><span class="tag tag-green">低</span></td><td>加工损耗</td><td class="td-actions"><a class="link">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-20</td><td>ING-005</td><td>鲫鱼</td><td>水产类</td><td>东海水产</td><td>280</td><td>¥24</td><td>¥6,720</td><td>248</td><td>32</td><td>¥768</td><td><span class="tag tag-red">11.4%</span></td><td><span class="tag tag-red">高</span></td><td>过期未用</td><td class="td-actions"><a class="link">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-20</td><td>ING-006</td><td>虾仁</td><td>水产类</td><td>东海水产</td><td>120</td><td>¥68</td><td>¥8,160</td><td>116</td><td>4</td><td>¥272</td><td><span class="tag tag-green">3.3%</span></td><td><span class="tag tag-green">低</span></td><td>加工损耗</td><td class="td-actions"><a class="link">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-22</td><td>ING-001</td><td>大白菜</td><td>蔬菜类</td><td>绿源农业</td><td>620</td><td>¥1.8</td><td>¥1,116</td><td>605</td><td>15</td><td>¥27</td><td><span class="tag tag-green">2.4%</span></td><td><span class="tag tag-green">低</span></td><td class="td-actions"><a class="link" data-reason="加工损耗">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-22</td><td>ING-002</td><td>菠菜</td><td>蔬菜类</td><td>绿源农业</td><td>380</td><td>¥2.5</td><td>¥950</td><td>345</td><td>35</td><td>¥87.5</td><td><span class="tag tag-orange">9.2%</span></td><td><span class="tag tag-orange">中</span></td><td class="td-actions"><a class="link" data-reason="储存变质">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-21</td><td>ING-003</td><td>猪肉(五花)</td><td>肉禽类</td><td>旺旺肉业</td><td>480</td><td>¥26</td><td>¥12,480</td><td>462</td><td>18</td><td>¥468</td><td><span class="tag tag-green">3.8%</span></td><td><span class="tag tag-green">低</span></td><td class="td-actions"><a class="link" data-reason="加工损耗">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-21</td><td>ING-004</td><td>鸡胸肉</td><td>肉禽类</td><td>旺旺肉业</td><td>320</td><td>¥20</td><td>¥6,400</td><td>308</td><td>12</td><td>¥240</td><td><span class="tag tag-green">3.8%</span></td><td><span class="tag tag-green">低</span></td><td class="td-actions"><a class="link" data-reason="加工损耗">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-20</td><td>ING-005</td><td>鲫鱼</td><td>水产类</td><td>东海水产</td><td>280</td><td>¥24</td><td>¥6,720</td><td>248</td><td>32</td><td>¥768</td><td><span class="tag tag-red">11.4%</span></td><td><span class="tag tag-red">高</span></td><td class="td-actions"><a class="link" data-reason="过期未用">损耗明细</a></td></tr>
|
||||
<tr><td>2026-04-20</td><td>ING-006</td><td>虾仁</td><td>水产类</td><td>东海水产</td><td>120</td><td>¥68</td><td>¥8,160</td><td>116</td><td>4</td><td>¥272</td><td><span class="tag tag-green">3.3%</span></td><td><span class="tag tag-green">低</span></td><td class="td-actions"><a class="link" data-reason="加工损耗">损耗明细</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -257,6 +306,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
<div class="filter-item"><label>菜品分类</label><select class="filter-select"><option>全部</option><option>荤菜</option><option>素菜</option></select></div>
|
||||
<div class="filter-item"><label>毛利率区间</label><select class="filter-select"><option>全部</option><option>>50%</option><option>40%-50%</option><option><40%</option></select></div>
|
||||
<button class="btn btn-primary">🔍 查询</button>
|
||||
<button class="btn btn-reset" onclick="resetFilter(1)">↻ 重置</button>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-primary"><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>
|
||||
@@ -296,7 +346,6 @@ const Modal={
|
||||
overlay.innerHTML=`<div class="modal ${extraClass||''}">
|
||||
<div class="modal__header"><h3>${title}</h3><button class="modal__close" onclick="Modal.close()">×</button></div>
|
||||
<div class="modal__body">${bodyHtml}</div>
|
||||
<div class="modal__footer"><button class="btn btn-default" onclick="Modal.close()">关闭</button></div>
|
||||
</div>`;
|
||||
document.body.appendChild(overlay);
|
||||
overlay.addEventListener('click',e=>{if(e.target===overlay)Modal.close();});
|
||||
@@ -311,7 +360,7 @@ const Modal={
|
||||
};
|
||||
|
||||
/* ===== 损耗明细弹窗 ===== */
|
||||
function showLossDetail(row){
|
||||
function showLossDetail(row,reasonText){
|
||||
/* 从表格行中读取数据 */
|
||||
const cells=row.querySelectorAll('td');
|
||||
const date=cells[0].textContent.trim();
|
||||
@@ -327,7 +376,7 @@ function showLossDetail(row){
|
||||
const lossAmt=cells[10].textContent.trim();
|
||||
const lossRate=cells[11].textContent.trim();
|
||||
const level=cells[12].textContent.trim();
|
||||
const reason=cells[13].textContent.trim();
|
||||
const reason=reasonText||'';
|
||||
|
||||
const html=`
|
||||
<div class="loss-info">
|
||||
@@ -351,10 +400,8 @@ function showLossDetail(row){
|
||||
<div class="loss-info__item"><span class="loss-info__label">损耗金额</span><span class="loss-info__value" style="color:var(--danger);font-weight:600;">${lossAmt}</span></div>
|
||||
<div class="loss-info__item"><span class="loss-info__label">损耗率</span><span class="loss-info__value">${lossRate}</span></div>
|
||||
<div class="loss-info__item"><span class="loss-info__label">预警等级</span><span class="loss-info__value">${level}</span></div>
|
||||
<div class="loss-info__item"><span class="loss-info__label">损耗原因</span><span class="loss-info__value">${reason}</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="loss-tip">⚠️ 建议:${reason==='过期未用'?'加强库存先进先出管理,缩短采购周期,减少积压。':reason==='储存变质'?'检查冷链温控设备,优化储存条件,缩短库存周转天数。':'优化加工切配流程,加强厨师技能培训,减少边角料浪费。'}</div>`;
|
||||
</div>`;
|
||||
|
||||
Modal.open('损耗明细 — '+name,html);
|
||||
}
|
||||
@@ -430,7 +477,7 @@ document.querySelectorAll('.tab-panel').forEach((panel,tabIdx)=>{
|
||||
panel.querySelectorAll('tbody tr').forEach(row=>{
|
||||
row.querySelectorAll('.td-actions .link').forEach(link=>{
|
||||
if(tabIdx===0 && link.textContent.includes('损耗明细')){
|
||||
link.addEventListener('click',()=>showLossDetail(row));
|
||||
link.addEventListener('click',()=>showLossDetail(row,link.getAttribute('data-reason')||''));
|
||||
}
|
||||
if(tabIdx===1 && link.textContent.includes('食材成本明细')){
|
||||
link.addEventListener('click',()=>showCostDetail(row));
|
||||
@@ -438,6 +485,65 @@ document.querySelectorAll('.tab-panel').forEach((panel,tabIdx)=>{
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/* ===== 食材分类级联选择器 ===== */
|
||||
var BENEFIT_CATEGORIES={'蔬菜类':['叶菜类','根茎类','瓜果类','菌菇类','豆荚类'],'肉禽类':['猪肉','牛肉','羊肉','鸡肉','鸭肉'],'水产类':['淡水鱼','海水鱼','虾蟹','贝类'],'蛋类':['鸡蛋','鸭蛋','鹅蛋'],'豆制品类':['大豆','豆腐','豆浆'],'粮油类':['大米','面粉','食用油'],'调味品类':['酱料','香辛料','调味汁']};
|
||||
var benefitL1Active='';
|
||||
function toggleBenefitCascade(){
|
||||
var panel=document.getElementById('benefitCascadePanel');
|
||||
var open=!panel.classList.contains('show');
|
||||
if(open){
|
||||
var rect=document.getElementById('benefitCascadeTrigger').getBoundingClientRect();
|
||||
panel.style.left=rect.left+'px';
|
||||
panel.style.top=(rect.bottom+4)+'px';
|
||||
benefitL1Active='';renderBenefitL1();document.getElementById('benefitCascadeL2').innerHTML='';
|
||||
}
|
||||
panel.classList.toggle('show',open);
|
||||
}
|
||||
function renderBenefitL1(){
|
||||
var col=document.getElementById('benefitCascadeL1');
|
||||
var html='<div class="cascade-col__title">一级分类</div>';
|
||||
html+='<div class="cascade-opt'+(benefitL1Active?'':' active')+'" onclick="selectBenefitCascade(\'\',\'\')">全部分类</div>';
|
||||
for(var k in BENEFIT_CATEGORIES){html+='<div class="cascade-opt'+(benefitL1Active===k?' active':'')+'" onmouseenter="hoverBenefitL1(\''+k+'\')" onclick="selectBenefitCascade(\''+k+'\',\'\')">'+k+'<span class="arrow-r">›</span></div>';}
|
||||
col.innerHTML=html;
|
||||
}
|
||||
function renderBenefitL2(l1){
|
||||
var col=document.getElementById('benefitCascadeL2');
|
||||
if(!l1){col.innerHTML='';return;}
|
||||
var subs=BENEFIT_CATEGORIES[l1]||[];
|
||||
var html='<div class="cascade-col__title">二级分类</div>';
|
||||
html+='<div class="cascade-opt" onclick="selectBenefitCascade(\''+l1+'\',\'\')">全部'+l1+'</div>';
|
||||
subs.forEach(function(s){html+='<div class="cascade-opt" onclick="selectBenefitCascade(\''+l1+'\',\''+s+'\')">'+s+'</div>';});
|
||||
col.innerHTML=html;
|
||||
}
|
||||
function hoverBenefitL1(l1){
|
||||
benefitL1Active=l1;
|
||||
document.querySelectorAll('#benefitCascadeL1 .cascade-opt').forEach(function(el,i){
|
||||
if(i===0) el.classList.toggle('active',!l1);
|
||||
else el.classList.toggle('active',el.textContent.replace('›','').trim()===l1);
|
||||
});
|
||||
renderBenefitL2(l1);
|
||||
}
|
||||
function selectBenefitCascade(l1,l2){
|
||||
var trig=document.getElementById('benefitCascadeTrigger');
|
||||
if(!l1){trig.textContent='全部';trig.classList.remove('has-value');}
|
||||
else if(!l2){trig.textContent=l1;trig.classList.add('has-value');}
|
||||
else{trig.textContent=l1+' / '+l2;trig.classList.add('has-value');}
|
||||
document.getElementById('benefitCascadePanel').classList.remove('show');
|
||||
}
|
||||
document.addEventListener('click',function(e){if(!e.target.closest('#benefitCategoryPicker'))document.getElementById('benefitCascadePanel').classList.remove('show');});
|
||||
|
||||
/* ===== 重置筛选 ===== */
|
||||
function resetFilter(tabIdx){
|
||||
var panel=document.querySelectorAll('.tab-panel')[tabIdx];
|
||||
if(!panel)return;
|
||||
panel.querySelectorAll('.filter-select').forEach(function(s){s.selectedIndex=0;});
|
||||
panel.querySelectorAll('.filter-input[type="date"]').forEach(function(inp){inp.value='';});
|
||||
if(tabIdx===0){
|
||||
var trig=document.getElementById('benefitCascadeTrigger');
|
||||
trig.textContent='全部';trig.classList.remove('has-value');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -83,6 +83,7 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
.tag-orange{background:#FFF7E6;color:var(--warning);}
|
||||
.tag-red{background:#FFF1F0;color:var(--danger);}
|
||||
.tag-gray{background:#F5F5F5;color:#999;}
|
||||
.tag-purple{background:#F9F0FF;color:#722ED1;}
|
||||
.link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);}.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);}
|
||||
@@ -96,6 +97,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
|
||||
/* 弹窗样式 */
|
||||
.modal-overlay{position:fixed;top:0;left:0;right:0;bottom:0;background:rgba(0,0,0,.45);z-index:1000;display:flex;align-items:center;justify-content:center;animation:modalFadeIn .2s ease;}
|
||||
.modal-overlay.layer{z-index:1010;background:rgba(0,0,0,.3);}
|
||||
.modal-overlay.closing{animation:modalFadeOut .2s ease forwards;}
|
||||
@keyframes modalFadeIn{from{opacity:0}to{opacity:1}}
|
||||
@keyframes modalFadeOut{from{opacity:1}to{opacity:0}}
|
||||
@@ -192,30 +194,30 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.pyramid__legend-values{display:flex;gap:24px;color:var(--text-secondary);}
|
||||
.pyramid__legend-values strong{color:var(--text-primary);}
|
||||
|
||||
/* 餐品明细(溯源关联)弹窗 */
|
||||
.dish-modal{width:980px;}
|
||||
.dish-header-info{display:flex;align-items:center;gap:24px;padding:14px 20px;background:#f8fafc;border-radius:var(--radius-md);margin-bottom:16px;font-size:var(--font-sm);flex-wrap:wrap;}
|
||||
/* 餐品明细弹窗 */
|
||||
.dish-modal{width:900px;}
|
||||
.dish-header-info{display:flex;align-items:center;gap:24px;padding:14px 20px;background:#f8fafc;border-radius:var(--radius-md);margin-bottom:20px;font-size:var(--font-sm);}
|
||||
.dish-header-info__item{display:flex;align-items:center;gap:6px;}
|
||||
.dish-header-info__label{color:var(--text-secondary);}
|
||||
.dish-header-info__value{color:var(--text-primary);font-weight:500;}
|
||||
.dish-tip{display:flex;align-items:center;gap:8px;padding:10px 16px;background:var(--primary-light);border-radius:var(--radius-sm);margin-bottom:16px;font-size:var(--font-sm);color:var(--primary);}
|
||||
.dish-tip svg{flex-shrink:0;}
|
||||
.dish-table{width:100%;border-collapse:collapse;font-size:var(--font-sm);margin-bottom:16px;}
|
||||
.dish-table thead th{background:#FAFAFA;padding:10px 12px;text-align:left;color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);white-space:nowrap;}
|
||||
.dish-table tbody td{padding:12px 12px;border-bottom:1px solid var(--border);color:var(--text-primary);white-space:nowrap;}
|
||||
.dish-table tbody tr:last-child td{border-bottom:none;}
|
||||
.dish-table tbody tr:hover{background:#F8FBFF;}
|
||||
.dish-table .td-num{font-variant-numeric:tabular-nums;}
|
||||
.dish-table .td-code{color:var(--text-secondary);font-family:monospace;font-size:12px;}
|
||||
.dish-table .td-num{text-align:right;font-family:monospace;}
|
||||
.dish-trace-link{color:var(--primary);cursor:pointer;font-size:var(--font-sm);display:inline-flex;align-items:center;gap:4px;}.dish-trace-link:hover{color:#40a9ff;}
|
||||
/* 底部汇总 */
|
||||
.dish-summary{display:flex;align-items:center;gap:32px;padding:16px 20px;background:#f8fafc;border-radius:var(--radius-md);font-size:var(--font-sm);}
|
||||
.dish-summary{display:flex;align-items:center;gap:32px;padding:16px 20px;background:#f8fafc;border-radius:var(--radius-md);font-size:var(--font-sm);margin-top:8px;}
|
||||
.dish-summary__item{display:flex;align-items:baseline;gap:6px;}
|
||||
.dish-summary__label{color:var(--text-secondary);}
|
||||
.dish-summary__value{font-size:var(--font-lg);font-weight:700;color:var(--text-primary);}
|
||||
.dish-summary__value.blue{color:var(--primary);}
|
||||
.dish-summary__value.green{color:var(--success);}
|
||||
.dish-summary__value.orange{color:var(--warning);}
|
||||
.dish-tip{display:flex;align-items:center;gap:6px;margin-top:16px;padding:10px 14px;background:#FFF7E6;border-radius:var(--radius-sm);font-size:var(--font-sm);color:var(--warning);}
|
||||
.dish-tip svg{flex-shrink:0;}
|
||||
|
||||
/* 营养师工作台弹窗 */
|
||||
.wb-modal{width:1060px;}
|
||||
@@ -264,6 +266,21 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.wb-plan__pct{font-size:11px;color:var(--text-secondary);margin-bottom:8px;}
|
||||
.wb-plan__items{font-size:12px;color:var(--text-secondary);line-height:1.9;}
|
||||
.wb-plan__actions{display:flex;gap:6px;margin-top:10px;}
|
||||
/* 周选择器:日期范围覆盖原生文字 */
|
||||
.week-picker{position:relative;display:inline-block;}
|
||||
.week-picker .filter-input{min-width:200px;color:transparent;}
|
||||
.week-picker .filter-input::-webkit-datetime-edit{color:transparent;}
|
||||
.week-picker__label{position:absolute;left:12px;top:50%;transform:translateY(-50%);font-size:var(--font-sm);color:var(--text-primary);pointer-events:none;white-space:nowrap;}
|
||||
|
||||
/* 页面信息栏 */
|
||||
.page-header-bar{display:flex;align-items:center;justify-content:space-between;background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);}
|
||||
.page-header-bar__left{display:flex;align-items:center;gap:12px;}
|
||||
.page-header-bar__title{font-size:var(--font-lg);font-weight:700;color:var(--text-primary);}
|
||||
.page-header-bar__meta{font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
.page-header-bar__right{display:flex;align-items:center;gap:12px;}
|
||||
.page-header-bar__right label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.page-header-bar__right .canteen-select{height:36px;border:2px solid var(--primary);border-radius:var(--radius-sm);padding:0 32px 0 14px;font-size:var(--font-sm);color:var(--primary);font-weight:500;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='%231890FF'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;min-width:140px;}
|
||||
|
||||
/* 建议卡片 */
|
||||
.wb-adv{border:1px solid var(--border);border-radius:6px;padding:10px 12px;margin-bottom:8px;}
|
||||
.wb-adv.ai{background:#f0f7ff;}
|
||||
@@ -293,6 +310,76 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.wb-adv-input{width:100%;min-height:70px;padding:8px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);resize:vertical;outline:none;font-family:inherit;}
|
||||
.wb-adv-input:focus{border-color:var(--primary);}
|
||||
.wb-adv-btns{display:flex;gap:6px;margin-top:8px;margin-bottom:12px;}
|
||||
/* 二级弹窗表单 */
|
||||
.wb-form-modal{width:520px;}
|
||||
.wb-form{display:flex;flex-direction:column;gap:16px;}
|
||||
.wb-form-row{display:flex;align-items:flex-start;gap:12px;}
|
||||
.wb-form-row__label{width:80px;flex-shrink:0;font-size:var(--font-sm);color:var(--text-secondary);line-height:32px;text-align:right;}
|
||||
.wb-form-row__label::after{content:'';} /* placeholder for required marker */
|
||||
.wb-form-row__label.required::after{content:' *';color:var(--danger);}
|
||||
.wb-form-row__body{flex:1;min-width:0;}
|
||||
.wb-form-input{width:100%;height:32px;padding:0 10px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;box-sizing:border-box;font-family:inherit;}
|
||||
.wb-form-input:focus{border-color:var(--primary);}
|
||||
.wb-form-select{width:100%;height:32px;padding:0 10px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;background:#fff;cursor:pointer;font-family:inherit;}
|
||||
.wb-form-select:focus{border-color:var(--primary);}
|
||||
.wb-form-textarea{width:100%;min-height:80px;padding:8px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);font-size:var(--font-sm);outline:none;resize:vertical;font-family:inherit;box-sizing:border-box;line-height:1.6;}
|
||||
.wb-form-textarea:focus{border-color:var(--primary);}
|
||||
.wb-form-date{width:160px;}
|
||||
.wb-form-date-range{display:flex;align-items:center;gap:8px;}
|
||||
.wb-form-date-range span{color:var(--text-secondary);font-size:var(--font-sm);}
|
||||
.wb-form-tags{display:flex;flex-wrap:wrap;gap:6px;}
|
||||
.wb-form-tags__add{display:flex;align-items:center;gap:4px;height:28px;padding:0 10px;border:1px dashed var(--border);border-radius:var(--radius-sm);font-size:12px;color:var(--text-secondary);cursor:pointer;background:none;}
|
||||
.wb-form-tags__add:hover{border-color:var(--primary);color:var(--primary);}
|
||||
.wb-form-tag{display:flex;align-items:center;gap:4px;height:28px;padding:0 10px;background:var(--primary-light);color:var(--primary);border-radius:var(--radius-sm);font-size:12px;}
|
||||
.wb-form-tag__close{cursor:pointer;font-size:14px;line-height:1;opacity:.6;}
|
||||
.wb-form-tag__close:hover{opacity:1;}
|
||||
.wb-form-radio-group{display:flex;gap:16px;height:32px;align-items:center;}
|
||||
.wb-form-radio{display:flex;align-items:center;gap:4px;font-size:var(--font-sm);color:var(--text-primary);cursor:pointer;}
|
||||
.wb-form-checkbox-group{display:flex;flex-wrap:wrap;gap:8px 16px;padding:6px 0;}
|
||||
.wb-form-checkbox{display:flex;align-items:center;gap:5px;font-size:var(--font-sm);color:var(--text-primary);cursor:pointer;padding:4px 10px;border:1px solid var(--border);border-radius:var(--radius-sm);transition:all .15s;}
|
||||
.wb-form-checkbox:has(input:checked){background:var(--primary-light);border-color:var(--primary);color:var(--primary);font-weight:500;}
|
||||
.wb-form-checkbox input{width:14px;height:14px;accent-color:var(--primary);}
|
||||
.wb-form-hint{font-size:11px;color:var(--text-placeholder);margin-top:4px;}
|
||||
/* 历史用餐明细表格 */
|
||||
.meal-history-table{width:100%;border-collapse:collapse;font-size:var(--font-sm);}
|
||||
.meal-history-table thead th{background:#FAFAFA;padding:10px 12px;text-align:left;color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
|
||||
.meal-history-table tbody td{padding:12px;color:var(--text-primary);border-bottom:1px solid #f0f0f0;}
|
||||
.meal-history-table tbody tr:last-child td{border-bottom:none;}
|
||||
.meal-history-table tbody tr:hover{background:#F8FBFF;}
|
||||
.score-tag{display:inline-block;padding:2px 8px;border-radius:4px;font-size:var(--font-sm);font-weight:600;}
|
||||
.score-green{color:#52C41A;background:#F6FFED;}
|
||||
.score-orange{color:#FA8C16;background:#FFF7E6;}
|
||||
/* 菜品偏好 */
|
||||
.dish-pref-section{display:flex;flex-direction:column;gap:12px;}
|
||||
.dish-pref-item__label{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:6px;}
|
||||
.dish-pref-item__tags{display:flex;gap:6px;flex-wrap:wrap;}
|
||||
.dish-tag{display:inline-block;padding:2px 10px;border-radius:4px;font-size:var(--font-xs);color:#52C41A;background:#F6FFED;border:1px solid #B7EB8F;}
|
||||
.dish-pref-item__value{font-size:var(--font-sm);color:var(--text-primary);}
|
||||
.dish-pref-item__big{font-size:var(--font-base);font-weight:600;color:var(--text-primary);}
|
||||
/* 妈妈味道 */
|
||||
.mom-section{background:#FFF8F0;border-radius:var(--radius-md);padding:12px 16px;}
|
||||
.mom-header{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
|
||||
.mom-header__icon{font-size:22px;}
|
||||
.mom-header__title{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);}
|
||||
.mom-header__sub{font-size:var(--font-xs);color:#FA8C16;margin-top:2px;}
|
||||
.mom-header__tags{display:flex;gap:6px;flex-wrap:wrap;}
|
||||
.mom-tag{display:inline-block;padding:2px 10px;border-radius:4px;font-size:var(--font-xs);color:#FA8C16;background:#FFF7E6;border:1px solid #FFD591;}
|
||||
/* 个性模型 */
|
||||
.model-section{background:#E6F7FF;border-radius:var(--radius-md);padding:12px 16px;margin-bottom:16px;}
|
||||
.model-header{display:flex;align-items:center;gap:10px;margin-bottom:10px;}
|
||||
.model-header__icon{font-size:22px;}
|
||||
.model-header__title{font-size:var(--font-sm);font-weight:600;color:var(--primary);}
|
||||
.model-header__sub{font-size:var(--font-xs);color:var(--text-secondary);margin-top:2px;}
|
||||
.model-header__tags{display:flex;gap:6px;flex-wrap:wrap;}
|
||||
.model-tag{display:inline-block;padding:2px 10px;border-radius:4px;font-size:var(--font-xs);color:var(--primary);background:#fff;border:1px solid #91D5FF;}
|
||||
.model-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:12px 20px;margin-bottom:16px;}
|
||||
.model-item__label{font-size:var(--font-xs);color:var(--text-secondary);margin-bottom:4px;}
|
||||
.model-item__big{font-size:var(--font-base);font-weight:600;color:var(--text-primary);}
|
||||
.model-item__value{font-size:var(--font-sm);}
|
||||
.risk-tag{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:4px;font-size:var(--font-xs);font-weight:500;}
|
||||
.risk-safe{background:#F6FFED;color:#52C41A;border:1px solid #B7EB8F;}
|
||||
.risk-warn{background:#FFF7E6;color:#FA8C16;border:1px solid #FFD591;}
|
||||
.model-footer{font-size:var(--font-xs);color:var(--text-secondary);padding:10px 12px;background:#F5F7FA;border-radius:var(--radius-sm);}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -360,6 +447,24 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
|
||||
<!-- 主内容 -->
|
||||
<main class="main">
|
||||
|
||||
<!-- 页面信息栏 -->
|
||||
<div class="page-header-bar">
|
||||
<div class="page-header-bar__left">
|
||||
<span class="page-header-bar__title">营养管理</span>
|
||||
<span class="page-header-bar__meta">2026-05-20 · 数据实时更新</span>
|
||||
</div>
|
||||
<div class="page-header-bar__right">
|
||||
<label>当前食堂</label>
|
||||
<select class="canteen-select" id="globalCanteen">
|
||||
<option value="1">一食堂(东区)</option>
|
||||
<option value="2">二食堂(西区)</option>
|
||||
<option value="3">三食堂(北区)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="stats-row">
|
||||
<div class="stat-card"><div class="stat-card__icon green">✅</div><div class="stat-card__info"><div class="stat-card__value">946人</div><div class="stat-card__label">今日达标人数</div></div></div>
|
||||
@@ -379,21 +484,17 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
<!-- Tab0: 餐次 -->
|
||||
<div class="tab-panel active">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>员工姓名/工号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>姓名/编号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>单位/部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>餐次</label><select class="filter-select"><option>全部</option><option>早餐</option><option>午餐</option><option>晚餐</option></select></div>
|
||||
<div class="filter-item"><label>订单来源</label><select class="filter-select"><option>全部</option><option>点餐</option><option>餐线</option></select></div>
|
||||
<div class="filter-item"><label>来源</label><select class="filter-select"><option>全部</option><option>点餐</option><option>餐线</option></select></div>
|
||||
<div class="filter-item"><label>营养达标状态</label><select class="filter-select"><option>全部</option><option>达标</option><option>超标</option></select></div>
|
||||
<div class="filter-item"><label>评分区间</label><select class="filter-select"><option>全部</option><option>90-100</option><option>80-89</option><option>70-79</option><option>60-69</option><option><60</option></select></div>
|
||||
<div class="filter-item"><label>是否超标</label><select class="filter-select"><option>全部</option><option>是</option><option>否</option></select></div>
|
||||
<div class="filter-item"><label>营养等级</label><select class="filter-select"><option>全部</option><option>低</option><option>中</option><option>高</option></select></div>
|
||||
<div class="filter-item"><label>日期范围</label><input class="filter-input" type="date"></div>
|
||||
<div class="filter-item"><label>日期</label><input class="filter-input" type="date" value="2026-05-21"></div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-default">📊 群体分析</button>
|
||||
<button class="btn btn-default">🔔 推送营养建议</button>
|
||||
<button class="btn btn-primary"><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"><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>
|
||||
@@ -403,14 +504,14 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>员工</th><th>部门</th><th>统计日期</th><th>餐次</th><th>订单来源</th><th>实际热量(kcal)</th><th>推荐热量(kcal)</th><th>蛋白质(g)</th><th>脂肪(g)</th><th>碳水(g)</th><th>钠(mg)</th><th>对比昨日</th><th>营养评分</th><th>营养等级</th><th>异常预警</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>就餐记录号</th><th>姓名/编号</th><th>单位/部门</th><th>统计日期</th><th>餐次</th><th>订单来源</th><th>实际热量(kcal)</th><th>推荐热量(kcal)</th><th>蛋白质(g)</th><th>脂肪(g)</th><th>碳水(g)</th><th>钠(mg)</th><th>对比昨日</th><th>营养评分</th><th>营养等级</th><th>营养达标状态</th><th>异常预警</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>张伟(EMP001)</td><td>研发部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-blue">点餐</span></td><td>2,156</td><td>2,250</td><td>78.3</td><td>72.1</td><td>285.4</td><td>1,820</td><td><span class="tag tag-green">↑+2分</span></td><td><span class="tag tag-green">88分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>李娜(EMP002)</td><td>市场部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-blue">点餐</span></td><td>1,842</td><td>1,800</td><td>65.2</td><td>58.7</td><td>241.3</td><td>2,180</td><td><span class="tag tag-gray">→持平</span></td><td><span class="tag tag-orange">76分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-orange">钠持续偏高</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>王磊(EMP003)</td><td>运营部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-gray">餐线</span></td><td>2,680</td><td>2,250</td><td>95.6</td><td>98.2</td><td>312.1</td><td>2,560</td><td><span class="tag tag-red">↓-3分</span></td><td><span class="tag tag-red">62分</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-red">热量+脂肪+钠均超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>赵敏(EMP004)</td><td>财务部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-gray">餐线</span></td><td>1,720</td><td>1,800</td><td>58.4</td><td>52.3</td><td>228.6</td><td>1,650</td><td><span class="tag tag-green">↑+1分</span></td><td><span class="tag tag-green">92分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>陈刚(EMP005)</td><td>人事部</td><td>2026-04-28</td><td>早餐</td><td><span class="tag tag-gray">餐线</span></td><td>2,050</td><td>2,250</td><td>72.1</td><td>68.4</td><td>270.2</td><td>1,980</td><td><span class="tag tag-gray">→持平</span></td><td><span class="tag tag-green">84分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>刘芳(EMP006)</td><td>市场部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-blue">点餐</span></td><td>1,480</td><td>1,800</td><td>48.6</td><td>42.1</td><td>198.5</td><td>1,420</td><td><span class="tag tag-orange">↓-2分</span></td><td><span class="tag tag-orange">70分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-orange">热量长期不达标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-001</td><td>张伟(EMP001)</td><td>采油一厂/研发部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-blue">点餐</span></td><td>2,156</td><td>2,250</td><td>78.3</td><td>72.1</td><td>285.4</td><td>1,820</td><td><span class="tag tag-green">↑+2分</span></td><td><span class="tag tag-green">88分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-002</td><td>李娜(EMP002)</td><td>采油二厂/市场部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-blue">点餐</span></td><td>1,842</td><td>1,800</td><td>65.2</td><td>58.7</td><td>241.3</td><td>2,180</td><td><span class="tag tag-gray">→持平</span></td><td><span class="tag tag-orange">76分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-orange">钠持续偏高</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-003</td><td>王磊(EMP003)</td><td>采油三厂/运营部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-gray">餐线</span></td><td>2,680</td><td>2,250</td><td>95.6</td><td>98.2</td><td>312.1</td><td>2,560</td><td><span class="tag tag-red">↓-3分</span></td><td><span class="tag tag-red">62分</span></td><td><span class="tag tag-green">高</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-red">热量+脂肪+钠均超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-004</td><td>赵敏(EMP004)</td><td>第五采气厂/财务部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-gray">餐线</span></td><td>1,720</td><td>1,800</td><td>58.4</td><td>52.3</td><td>228.6</td><td>1,650</td><td><span class="tag tag-green">↑+1分</span></td><td><span class="tag tag-green">92分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-005</td><td>陈刚(EMP005)</td><td>油气工艺所/人事部</td><td>2026-04-28</td><td>早餐</td><td><span class="tag tag-gray">餐线</span></td><td>2,050</td><td>2,250</td><td>72.1</td><td>68.4</td><td>270.2</td><td>1,980</td><td><span class="tag tag-gray">→持平</span></td><td><span class="tag tag-green">84分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-006</td><td>刘芳(EMP006)</td><td>采油二厂/市场部</td><td>2026-04-28</td><td>午餐</td><td><span class="tag tag-blue">点餐</span></td><td>1,480</td><td>1,800</td><td>48.6</td><td>42.1</td><td>198.5</td><td>1,420</td><td><span class="tag tag-orange">↓-2分</span></td><td><span class="tag tag-orange">70分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-orange">热量长期不达标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -421,20 +522,16 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
<!-- Tab1: 按日 -->
|
||||
<div class="tab-panel">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>员工姓名/工号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>订单来源</label><select class="filter-select"><option>全部</option><option>点餐</option><option>餐线</option></select></div>
|
||||
<div class="filter-item"><label>姓名/编号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>单位/部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>来源</label><select class="filter-select"><option>全部</option><option>点餐</option><option>餐线</option></select></div>
|
||||
<div class="filter-item"><label>营养达标状态</label><select class="filter-select"><option>全部</option><option>达标</option><option>超标</option></select></div>
|
||||
<div class="filter-item"><label>评分区间</label><select class="filter-select"><option>全部</option><option>90-100</option><option>80-89</option><option>70-79</option><option>60-69</option><option><60</option></select></div>
|
||||
<div class="filter-item"><label>是否超标</label><select class="filter-select"><option>全部</option><option>是</option><option>否</option></select></div>
|
||||
<div class="filter-item"><label>营养等级</label><select class="filter-select"><option>全部</option><option>低</option><option>中</option><option>高</option></select></div>
|
||||
<div class="filter-item"><label>日期范围</label><input class="filter-input" type="date"></div>
|
||||
<div class="filter-item"><label>日期</label><input class="filter-input" type="date" value="2026-05-21"></div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-default">📊 群体分析</button>
|
||||
<button class="btn btn-default">🔔 推送营养建议</button>
|
||||
<button class="btn btn-primary"><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"><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>
|
||||
@@ -444,36 +541,34 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>员工</th><th>部门</th><th>统计日期</th><th>统计范围</th><th>订单来源</th><th>日总热量(kcal)</th><th>推荐热量(kcal)</th><th>蛋白质(g)</th><th>脂肪(g)</th><th>碳水(g)</th><th>钠(mg)</th><th>对比昨日</th><th>营养评分</th><th>营养等级</th><th>异常预警</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>就餐记录号</th><th>姓名/编号</th><th>单位/部门</th><th>统计日期</th><th>订单来源</th><th>日总热量(kcal)</th><th>推荐热量(kcal)</th><th>蛋白质(g)</th><th>脂肪(g)</th><th>碳水(g)</th><th>钠(mg)</th><th>对比昨日</th><th>营养评分</th><th>营养等级</th><th>营养达标状态</th><th>异常预警</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>张伟(EMP001)</td><td>研发部</td><td>2026-04-28</td><td>全餐次</td><td><span class="tag tag-blue">点餐</span></td><td>2,186</td><td>2,250</td><td>76.8</td><td>70.9</td><td>281.6</td><td>1,790</td><td><span class="tag tag-green">↑+1.2%</span></td><td><span class="tag tag-green">86分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>李娜(EMP002)</td><td>市场部</td><td>2026-04-28</td><td>全餐次</td><td><span class="tag tag-blue">点餐</span></td><td>1,864</td><td>1,800</td><td>64.6</td><td>57.8</td><td>238.2</td><td>2,140</td><td><span class="tag tag-orange">↓-0.8%</span></td><td><span class="tag tag-orange">74分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-orange">钠连续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>王磊(EMP003)</td><td>运营部</td><td>2026-04-28</td><td>全餐次</td><td><span class="tag tag-gray">餐线</span></td><td>2,642</td><td>2,250</td><td>93.4</td><td>95.1</td><td>308.8</td><td>2,510</td><td><span class="tag tag-red">↑+2.6%</span></td><td><span class="tag tag-red">60分</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-red">三项持续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>赵敏(EMP004)</td><td>财务部</td><td>2026-04-28</td><td>全餐次</td><td><span class="tag tag-gray">餐线</span></td><td>1,746</td><td>1,800</td><td>57.6</td><td>51.4</td><td>226.3</td><td>1,620</td><td><span class="tag tag-green">↑+0.6%</span></td><td><span class="tag tag-green">90分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-001</td><td>张伟(EMP001)</td><td>采油一厂/研发部</td><td>2026-04-28</td><td><span class="tag tag-blue">点餐</span></td><td>2,186</td><td>2,250</td><td>76.8</td><td>70.9</td><td>281.6</td><td>1,790</td><td><span class="tag tag-green">↑+1.2%</span></td><td><span class="tag tag-green">86分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-002</td><td>李娜(EMP002)</td><td>采油二厂/市场部</td><td>2026-04-28</td><td><span class="tag tag-blue">点餐</span></td><td>1,864</td><td>1,800</td><td>64.6</td><td>57.8</td><td>238.2</td><td>2,140</td><td><span class="tag tag-orange">↓-0.8%</span></td><td><span class="tag tag-orange">74分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-orange">钠连续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-003</td><td>王磊(EMP003)</td><td>采油三厂/运营部</td><td>2026-04-28</td><td><span class="tag tag-gray">餐线</span></td><td>2,642</td><td>2,250</td><td>93.4</td><td>95.1</td><td>308.8</td><td>2,510</td><td><span class="tag tag-red">↑+2.6%</span></td><td><span class="tag tag-red">60分</span></td><td><span class="tag tag-green">高</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-red">三项持续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-004</td><td>赵敏(EMP004)</td><td>第五采气厂/财务部</td><td>2026-04-28</td><td><span class="tag tag-gray">餐线</span></td><td>1,746</td><td>1,800</td><td>57.6</td><td>51.4</td><td>226.3</td><td>1,620</td><td><span class="tag tag-green">↑+0.6%</span></td><td><span class="tag tag-green">90分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-005</td><td>陈刚(EMP005)</td><td>油气工艺所/人事部</td><td>2026-04-28</td><td><span class="tag tag-gray">餐线</span></td><td>2,050</td><td>2,250</td><td>72.1</td><td>68.4</td><td>270.2</td><td>1,980</td><td><span class="tag tag-gray">→持平</span></td><td><span class="tag tag-green">84分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-006</td><td>刘芳(EMP006)</td><td>采油二厂/市场部</td><td>2026-04-28</td><td><span class="tag tag-blue">点餐</span></td><td>1,480</td><td>1,800</td><td>48.6</td><td>42.1</td><td>198.5</td><td>1,420</td><td><span class="tag tag-orange">↓-2.1%</span></td><td><span class="tag tag-orange">70分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-orange">热量长期不达标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination"><span>显示 4 条,共 946 条</span><button class="page-btn">‹</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">›</button></div>
|
||||
<div class="pagination"><span>显示 6 条,共 946 条</span><button class="page-btn">‹</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">›</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab2: 按周 -->
|
||||
<div class="tab-panel">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>员工姓名/工号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>订单来源</label><select class="filter-select"><option>全部</option><option>点餐</option><option>餐线</option></select></div>
|
||||
<div class="filter-item"><label>姓名/编号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>单位/部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>来源</label><select class="filter-select"><option>全部</option><option>点餐</option><option>餐线</option></select></div>
|
||||
<div class="filter-item"><label>营养达标状态</label><select class="filter-select"><option>全部</option><option>达标</option><option>超标</option></select></div>
|
||||
<div class="filter-item"><label>评分区间</label><select class="filter-select"><option>全部</option><option>90-100</option><option>80-89</option><option>70-79</option><option>60-69</option><option><60</option></select></div>
|
||||
<div class="filter-item"><label>是否超标</label><select class="filter-select"><option>全部</option><option>是</option><option>否</option></select></div>
|
||||
<div class="filter-item"><label>营养等级</label><select class="filter-select"><option>全部</option><option>低</option><option>中</option><option>高</option></select></div>
|
||||
<div class="filter-item"><label>周范围</label><input class="filter-input" type="week"></div>
|
||||
<div class="filter-item"><label>周范围</label><div class="week-picker"><input class="filter-input week-range-input" type="week" value="2026-W21"><span class="week-picker__label">2026-05-18 ~ 2026-05-24</span></div></div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-default">📊 群体分析</button>
|
||||
<button class="btn btn-default">🔔 推送营养建议</button>
|
||||
<button class="btn btn-primary"><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"><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>
|
||||
@@ -483,34 +578,35 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>员工</th><th>部门</th><th>统计周</th><th>统计范围</th><th>订单来源</th><th>周均热量(kcal)</th><th>周均推荐热量(kcal)</th><th>周均蛋白质(g)</th><th>周均脂肪(g)</th><th>周均碳水(g)</th><th>周均钠(mg)</th><th>对比上周</th><th>营养评分</th><th>营养等级</th><th>异常预警</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>就餐记录号</th><th>姓名/编号</th><th>单位/部门</th><th>统计周</th><th>订单来源</th><th>周均热量(kcal)</th><th>推荐热量(kcal)</th><th>蛋白质(g)</th><th>脂肪(g)</th><th>碳水(g)</th><th>钠(mg)</th><th>对比上周</th><th>营养评分</th><th>营养等级</th><th>营养达标状态</th><th>异常预警</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>张伟(EMP001)</td><td>研发部</td><td>2026年第18周</td><td>全餐次</td><td><span class="tag tag-blue">点餐</span></td><td>2,186</td><td>2,250</td><td>76.8</td><td>70.9</td><td>281.6</td><td>1,790</td><td><span class="tag tag-green">↑+1.2%</span></td><td><span class="tag tag-green">86分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>李娜(EMP002)</td><td>市场部</td><td>2026年第18周</td><td>全餐次</td><td><span class="tag tag-blue">点餐</span></td><td>1,864</td><td>1,800</td><td>64.6</td><td>57.8</td><td>238.2</td><td>2,140</td><td><span class="tag tag-orange">↓-0.8%</span></td><td><span class="tag tag-orange">74分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-orange">钠连续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>王磊(EMP003)</td><td>运营部</td><td>2026年第18周</td><td>全餐次</td><td><span class="tag tag-gray">餐线</span></td><td>2,642</td><td>2,250</td><td>93.4</td><td>95.1</td><td>308.8</td><td>2,510</td><td><span class="tag tag-red">↑+2.6%</span></td><td><span class="tag tag-red">60分</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-red">三项持续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>赵敏(EMP004)</td><td>财务部</td><td>2026年第18周</td><td>全餐次</td><td><span class="tag tag-gray">餐线</span></td><td>1,746</td><td>1,800</td><td>57.6</td><td>51.4</td><td>226.3</td><td>1,620</td><td><span class="tag tag-green">↑+0.6%</span></td><td><span class="tag tag-green">90分</span></td><td><span class="tag tag-green">低</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-001</td><td>张伟(EMP001)</td><td>采油一厂/研发部</td><td>2026年第18周</td><td><span class="tag tag-blue">点餐</span></td><td>2,186</td><td>2,250</td><td>76.8</td><td>70.9</td><td>281.6</td><td>1,790</td><td><span class="tag tag-green">↑+1.2%</span></td><td><span class="tag tag-green">86分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-002</td><td>李娜(EMP002)</td><td>采油二厂/市场部</td><td>2026年第18周</td><td><span class="tag tag-blue">点餐</span></td><td>1,864</td><td>1,800</td><td>64.6</td><td>57.8</td><td>238.2</td><td>2,140</td><td><span class="tag tag-orange">↓-0.8%</span></td><td><span class="tag tag-orange">74分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-orange">钠连续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-003</td><td>王磊(EMP003)</td><td>采油三厂/运营部</td><td>2026年第18周</td><td><span class="tag tag-gray">餐线</span></td><td>2,642</td><td>2,250</td><td>93.4</td><td>95.1</td><td>308.8</td><td>2,510</td><td><span class="tag tag-red">↑+2.6%</span></td><td><span class="tag tag-red">60分</span></td><td><span class="tag tag-green">高</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-red">三项持续超标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-004</td><td>赵敏(EMP004)</td><td>第五采气厂/财务部</td><td>2026年第18周</td><td><span class="tag tag-gray">餐线</span></td><td>1,746</td><td>1,800</td><td>57.6</td><td>51.4</td><td>226.3</td><td>1,620</td><td><span class="tag tag-green">↑+0.6%</span></td><td><span class="tag tag-green">90分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-005</td><td>陈刚(EMP005)</td><td>油气工艺所/人事部</td><td>2026年第18周</td><td><span class="tag tag-gray">餐线</span></td><td>2,050</td><td>2,250</td><td>72.1</td><td>68.4</td><td>270.2</td><td>1,980</td><td><span class="tag tag-gray">→持平</span></td><td><span class="tag tag-green">84分</span></td><td><span class="tag tag-red">低</span></td><td><span class="tag tag-green">达标</span></td><td>—</td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>M-20260428-006</td><td>刘芳(EMP006)</td><td>采油二厂/市场部</td><td>2026年第18周</td><td><span class="tag tag-blue">点餐</span></td><td>1,480</td><td>1,800</td><td>48.6</td><td>42.1</td><td>198.5</td><td>1,420</td><td><span class="tag tag-orange">↓-2.1%</span></td><td><span class="tag tag-orange">70分</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-red">超标</span></td><td><span class="tag tag-orange">热量长期不达标</span></td><td class="td-actions"><a class="link">营养明细</a> <a class="link">餐品明细</a> <a class="link">查看用户信息</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div class="pagination"><span>显示 4 条,共 946 条</span><button class="page-btn">‹</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">›</button></div>
|
||||
<div class="pagination"><span>显示 6 条,共 946 条</span><button class="page-btn">‹</button><button class="page-btn active">1</button><button class="page-btn">2</button><button class="page-btn">3</button><button class="page-btn">›</button></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tab3: 营养档案 -->
|
||||
<div class="tab-panel">
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>员工姓名/工号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>人员类别</label><select class="filter-select"><option>全部</option><option>会员</option><option>非会员</option></select></div>
|
||||
<div class="filter-item"><label>员工姓名/编号</label><input class="filter-input" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>单位部门</label><select class="filter-select"><option>全部</option></select></div>
|
||||
<div class="filter-item"><label>人员类别</label><select class="filter-select"><option>全部</option><option>会员用户</option><option>普通用户</option><option>员工</option><option>工作人员</option><option>外部人员</option></select></div>
|
||||
<div class="filter-item"><label>风险等级</label><select class="filter-select"><option>全部</option><option>低</option><option>中</option><option>高</option></select></div>
|
||||
<div class="filter-item"><label>干预状态</label><select class="filter-select"><option>全部</option><option>跟进中</option><option>已稳定</option><option>未跟进</option><option>需复诊</option></select></div>
|
||||
<div class="filter-item"><label>营养师</label><select class="filter-select"><option>全部</option><option>林营养师</option><option>周营养师</option></select></div>
|
||||
<div class="filter-item"><label>跟进营养师</label><select class="filter-select"><option>全部</option><option>林营养师</option><option>周营养师</option></select></div>
|
||||
<div class="filter-item"><label>慢病标签</label><select class="filter-select"><option>全部</option><option>高血压</option><option>高血脂</option><option>糖尿病</option><option>BMI偏低</option><option>高尿酸</option></select></div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
</div>
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-primary">➕ 新建跟进</button>
|
||||
<button class="btn btn-default">🔔 批量推送建议</button>
|
||||
<button class="btn btn-primary"><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"><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>
|
||||
@@ -521,16 +617,16 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>用户</th><th>部门</th><th>人员类别</th><th>慢病标签</th><th>近30日评分</th><th>评分趋势</th><th>最近异常</th><th>风险等级</th><th>干预状态</th><th>营养师</th><th>最近跟进</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>姓名/编号</th><th>单位/部门</th><th>人员类别</th><th>慢病标签</th><th>近30日评分</th><th>评分趋势</th><th>最近异常</th><th>风险等级</th><th>干预状态</th><th>最近跟进</th><th>跟进营养师</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>张伟(EMP001)</td><td>研发部</td><td><span class="tag tag-orange">会员</span></td><td>无</td><td>86分</td><td><span class="tag tag-green">↑ 稳中有升</span></td><td>—</td><td><span class="tag tag-green">低</span></td><td><span class="tag tag-gray">已稳定</span></td><td>林营养师</td><td>2026-04-26</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>李娜(EMP002)</td><td>市场部</td><td><span class="tag tag-orange">会员</span></td><td><span class="tag tag-red">高血压</span></td><td>74分</td><td><span class="tag tag-gray">→ 持平</span></td><td><span class="tag tag-orange">钠超标</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>林营养师</td><td>2026-05-08</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>王磊(EMP003)</td><td>运营部</td><td><span class="tag tag-gray">非会员</span></td><td><span class="tag tag-red">高血脂</span></td><td>60分</td><td><span class="tag tag-red">↓ 下降</span></td><td><span class="tag tag-red">热量+脂肪+钠</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-blue">跟进中</span></td><td>周营养师</td><td>2026-05-10</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>赵敏(EMP004)</td><td>财务部</td><td><span class="tag tag-orange">会员</span></td><td><span class="tag tag-red">糖尿病</span></td><td>90分</td><td><span class="tag tag-green">↑ 改善</span></td><td>—</td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>林营养师</td><td>2026-05-09</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>陈刚(EMP005)</td><td>人事部</td><td><span class="tag tag-gray">非会员</span></td><td>无</td><td>84分</td><td><span class="tag tag-gray">→ 持平</span></td><td>—</td><td><span class="tag tag-green">低</span></td><td><span class="tag tag-gray">未跟进</span></td><td>—</td><td>—</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>刘芳(EMP006)</td><td>市场部</td><td><span class="tag tag-orange">会员</span></td><td>无</td><td>70分</td><td><span class="tag tag-orange">↓ 轻度下降</span></td><td><span class="tag tag-orange">热量长期不达标</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>周营养师</td><td>2026-05-07</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>孙磊(EMP010)</td><td>行政部</td><td><span class="tag tag-gray">非会员</span></td><td><span class="tag tag-red">高血压·高尿酸</span></td><td>64分</td><td><span class="tag tag-red">↓ 下降</span></td><td><span class="tag tag-red">钠+尿酸</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-orange">需复诊</span></td><td>周营养师</td><td>2026-05-05</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>钱芳(EMP011)</td><td>销售部</td><td><span class="tag tag-orange">会员</span></td><td><span class="tag tag-orange">BMI偏低</span></td><td>82分</td><td><span class="tag tag-green">↑ 改善</span></td><td>—</td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>林营养师</td><td>2026-05-06</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>张伟(EMP001)</td><td>采油一厂/研发部</td><td><span class="tag tag-orange">会员用户</span></td><td>无</td><td>86分</td><td><span class="tag tag-green">↑ 稳中有升</span></td><td>—</td><td><span class="tag tag-green">低</span></td><td><span class="tag tag-gray">已稳定</span></td><td>2026-04-26</td><td>林营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>李娜(EMP002)</td><td>采油二厂/市场部</td><td><span class="tag tag-orange">会员用户</span></td><td><span class="tag tag-red">高血压</span></td><td>74分</td><td><span class="tag tag-gray">→ 持平</span></td><td><span class="tag tag-orange">钠超标</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>2026-05-08</td><td>林营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>王磊(EMP003)</td><td>采油三厂/运营部</td><td><span class="tag tag-blue">员工</span></td><td><span class="tag tag-red">高血脂</span></td><td>60分</td><td><span class="tag tag-red">↓ 下降</span></td><td><span class="tag tag-red">热量+脂肪+钠</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-blue">跟进中</span></td><td>2026-05-10</td><td>周营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>赵敏(EMP004)</td><td>第五采气厂/财务部</td><td><span class="tag tag-orange">会员用户</span></td><td><span class="tag tag-red">糖尿病</span></td><td>90分</td><td><span class="tag tag-green">↑ 改善</span></td><td>—</td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>2026-05-09</td><td>林营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>陈刚(EMP005)</td><td>油气工艺所/人事部</td><td><span class="tag tag-gray">普通用户</span></td><td>无</td><td>84分</td><td><span class="tag tag-gray">→ 持平</span></td><td>—</td><td><span class="tag tag-green">低</span></td><td><span class="tag tag-gray">未跟进</span></td><td>—</td><td>—</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>刘芳(EMP006)</td><td>采油二厂/市场部</td><td><span class="tag tag-orange">会员用户</span></td><td>无</td><td>70分</td><td><span class="tag tag-orange">↓ 轻度下降</span></td><td><span class="tag tag-orange">热量长期不达标</span></td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>2026-05-07</td><td>周营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>孙磊(EMP010)</td><td>数质中心/行政部</td><td><span class="tag tag-blue">工作人员</span></td><td><span class="tag tag-red">高血压·高尿酸</span></td><td>64分</td><td><span class="tag tag-red">↓ 下降</span></td><td><span class="tag tag-red">钠+尿酸</span></td><td><span class="tag tag-red">高</span></td><td><span class="tag tag-orange">需复诊</span></td><td>2026-05-05</td><td>周营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
<tr><td>钱芳(EMP011)</td><td>供水公司/销售部</td><td><span class="tag tag-purple">外部人员</span></td><td><span class="tag tag-orange">BMI偏低</span></td><td>82分</td><td><span class="tag tag-green">↑ 改善</span></td><td>—</td><td><span class="tag tag-orange">中</span></td><td><span class="tag tag-blue">跟进中</span></td><td>2026-05-06</td><td>林营养师</td><td class="td-actions"><a class="link">🍽️ 营养管理</a> <a class="link">查看用户信息</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -545,6 +641,20 @@ function switchTab(idx){document.querySelectorAll('.page-tab').forEach((t,i)=>t.
|
||||
function toggleSubgroup(header){header.parentElement.classList.toggle('open');}
|
||||
(function(){var active=document.querySelector('.sidebar-item.active');if(!active)return;var sub=active.closest('.sidebar-subgroup');if(sub)sub.classList.add('open');})();
|
||||
|
||||
/* 周选择器:变更时更新覆盖层日期范围 */
|
||||
document.querySelectorAll('.week-range-input').forEach(function(input){
|
||||
input.addEventListener('change',function(){
|
||||
var v=this.value; if(!v)return;
|
||||
var parts=v.split('-W'), year=parseInt(parts[0]), week=parseInt(parts[1]);
|
||||
var d=new Date(year,0,4);
|
||||
d.setDate(d.getDate()-(d.getDay()||7)+1+(week-1)*7);
|
||||
var mon=d.toISOString().slice(0,10);
|
||||
var sun=new Date(d); sun.setDate(sun.getDate()+6);
|
||||
var label=this.parentElement.querySelector('.week-picker__label');
|
||||
if(label) label.textContent=mon+' ~ '+sun.toISOString().slice(0,10);
|
||||
});
|
||||
});
|
||||
|
||||
/* ========== 弹窗基础 ========== */
|
||||
const Modal = {
|
||||
open(title, bodyHtml, extraClass, footerHtml) {
|
||||
@@ -560,7 +670,24 @@ const Modal = {
|
||||
document.body.appendChild(overlay);
|
||||
},
|
||||
close() {
|
||||
const o = document.querySelector('.modal-overlay');
|
||||
const o = document.querySelector('.modal-overlay:not(.layer)');
|
||||
if (!o) return;
|
||||
o.classList.add('closing');
|
||||
setTimeout(() => o.remove(), 200);
|
||||
},
|
||||
openLayer(title, bodyHtml, extraClass, footerHtml) {
|
||||
const overlay = document.createElement('div');
|
||||
overlay.className = 'modal-overlay layer';
|
||||
overlay.innerHTML = `<div class="modal ${extraClass||''}">
|
||||
<div class="modal-header"><div class="modal-title">${title}</div><button class="modal-close" onclick="Modal.closeLayer()">×</button></div>
|
||||
<div class="modal-body">${bodyHtml}</div>
|
||||
${footerHtml ? '<div class="modal-footer">'+footerHtml+'</div>' : ''}
|
||||
</div>`;
|
||||
overlay.addEventListener('click', e => { if (e.target === overlay) Modal.closeLayer(); });
|
||||
document.body.appendChild(overlay);
|
||||
},
|
||||
closeLayer() {
|
||||
const o = document.querySelector('.modal-overlay.layer');
|
||||
if (!o) return;
|
||||
o.classList.add('closing');
|
||||
setTimeout(() => o.remove(), 200);
|
||||
@@ -569,34 +696,58 @@ const Modal = {
|
||||
|
||||
/* ========== 十维档案 ========== */
|
||||
const userProfiles = {
|
||||
'张伟': { dept:'研发部', age:38, gender:'男', height:'175cm', weight:'72kg', bmi:'22.9', activity:'中度活动',
|
||||
'张伟': { dept:'公司机关/研发部', age:32, gender:'男', height:'175cm', weight:'72kg', bmi:'23.5', activity:'中等',
|
||||
disease:'无', chronic:'无', medicine:'无', family:'高血压(父)',
|
||||
examDate:'2026-03-15', bp:'125/80', glucose:'5.2', lipid:'正常', uric:'380', liver:'正常', kidney:'正常',
|
||||
taste:'偏辣', region:'川菜、湘菜', taboo:'无', allergy:'花生',
|
||||
exercise:'6000步/日', weightTrend:'稳定', bodyFat:'18%', heartRate:'68', sleep:'7.5h', stress:'低', source:'智能手环',
|
||||
meals30:'58次', hotDish:'宫保鸡丁、番茄牛腩', avgCal:'680kcal', nutriRate:'88%',
|
||||
favDish:'宫保鸡丁、清炒西兰花', recDish:'三文鱼沙拉', avoidDish:'油炸花生', topRate:'番茄牛腩(4.8)', repurchase:'宫保鸡丁',
|
||||
hometown:'四川成都', momTag:'麻辣鲜香', momList:'回锅肉、麻婆豆腐', memory:'妈妈的回锅肉', recTry:'水煮鱼',
|
||||
modelVer:'v2.3', modelTime:'2026-04-20', recCal:'2100kcal', nutriFocus:'蛋白质+膳食纤维', risk:'无', tags:'运动达人、川菜爱好者', confidence:'92%' },
|
||||
'李娜': { dept:'市场部', age:34, gender:'女', height:'163cm', weight:'52kg', bmi:'19.8', activity:'轻度活动',
|
||||
meals30:'86次', hotDish:'宫保鸡丁、番茄牛腩', avgCal:'2,186 kcal/天', nutriRate:'88%',
|
||||
proteinRate:'92%', highFatRate:'8%', preferMeal:'午餐', lastMeal:'2026-04-28 午餐',
|
||||
mealHistory:[
|
||||
{date:'2026-04-28',meal:'午餐',dishes:'清蒸鱼、炒西兰花、米饭、紫菜蛋花汤',cal:'832 kcal',score:95},
|
||||
{date:'2026-04-28',meal:'早餐',dishes:'小米粥、卤蛋、凉拌黄瓜',cal:'380 kcal',score:92},
|
||||
{date:'2026-04-27',meal:'午餐',dishes:'杂粮饭、清蒸鱼、蒜蓉菠菜',cal:'798 kcal',score:94},
|
||||
{date:'2026-04-26',meal:'午餐',dishes:'米饭、宫保鸡丁、炒西兰花、汤',cal:'906 kcal',score:86},
|
||||
{date:'2026-04-25',meal:'晚餐',dishes:'杂粮饭、清蒸鱼、炒时蔬',cal:'716 kcal',score:96}
|
||||
],
|
||||
favDish:'宫保鸡丁、清炒西兰花、杂粮饭', recDish:'三文鱼沙拉、蒜蓉菠菜', avoidDish:'油炸花生', topRate:'宫保鸡丁(94分)', repurchase:'宫保鸡丁(近30日18次)',
|
||||
hometown:'四川成都', momTag:'麻辣、红油、鲜香', momList:'回锅肉、麻婆豆腐、水煮鱼', memory:'从小常吃妈妈做的回锅肉,奠定了麻辣口味偏好。', recTry:'川味水煮鱼套餐(已上架一号食堂)',
|
||||
modelVer:'v2.3', modelTime:'2026-04-20', recCal:'2,250 kcal', nutriFocus:'蛋白质+膳食纤维', risk:'无风险', tags:'清淡偏好、中度活动、无慢病', confidence:'94%', nextUpdate:'2026-05-28' },
|
||||
'李娜': { dept:'采油二厂/市场部', age:28, gender:'女', height:'163cm', weight:'52kg', bmi:'19.6', activity:'轻度',
|
||||
disease:'无', chronic:'无', medicine:'无', family:'糖尿病(母)',
|
||||
examDate:'2026-02-20', bp:'110/70', glucose:'4.8', lipid:'正常', uric:'290', liver:'正常', kidney:'正常',
|
||||
taste:'清淡', region:'粤菜、日料', taboo:'无', allergy:'海鲜(虾蟹)',
|
||||
exercise:'4000步/日', weightTrend:'稳定', bodyFat:'22%', heartRate:'72', sleep:'7h', stress:'中', source:'手机计步',
|
||||
meals30:'52次', hotDish:'蒸鱼、蔬菜沙拉', avgCal:'520kcal', nutriRate:'92%',
|
||||
favDish:'清蒸鲈鱼、藜麦沙拉', recDish:'牛油果吐司', avoidDish:'麻辣火锅', topRate:'藜麦沙拉(4.9)', repurchase:'清蒸鲈鱼',
|
||||
hometown:'广东广州', momTag:'鲜甜清润', momList:'老火靓汤、白切鸡', memory:'周末的煲汤', recTry:'椰子鸡',
|
||||
modelVer:'v2.3', modelTime:'2026-04-18', recCal:'1650kcal', nutriFocus:'钙+铁+维生素D', risk:'注意糖摄入', tags:'轻食主义、养生达人', confidence:'95%' }
|
||||
meals30:'52次', hotDish:'清蒸鲈鱼、藜麦沙拉', avgCal:'1,650 kcal/天', nutriRate:'92%',
|
||||
proteinRate:'95%', highFatRate:'5%', preferMeal:'午餐', lastMeal:'2026-04-28 午餐',
|
||||
mealHistory:[
|
||||
{date:'2026-04-28',meal:'午餐',dishes:'藜麦沙拉、清蒸鲈鱼、蒜蓉西兰花',cal:'680 kcal',score:96},
|
||||
{date:'2026-04-28',meal:'早餐',dishes:'牛油果吐司、酸奶、水果',cal:'420 kcal',score:94},
|
||||
{date:'2026-04-27',meal:'午餐',dishes:'三文鱼沙拉、杂粮饭、蔬菜汤',cal:'720 kcal',score:97},
|
||||
{date:'2026-04-26',meal:'午餐',dishes:'清蒸鲈鱼、藜麦饭、凉拌木耳',cal:'650 kcal',score:95},
|
||||
{date:'2026-04-25',meal:'晚餐',dishes:'蔬菜沙拉、鸡胸肉、全麦面包',cal:'580 kcal',score:93}
|
||||
],
|
||||
favDish:'清蒸鲈鱼、藜麦沙拉、杂粮饭', recDish:'蒜蓉菠菜、紫菜蛋花汤', avoidDish:'暂无', topRate:'清蒸鱼(96分)', repurchase:'清蒸鱼(近30日21次)',
|
||||
hometown:'广东广州', momTag:'清炖、甜咸适中、河鲜', momList:'松鼠桂鱼、响油鳝糊、腌笃鲜', memory:'从小常吃妈妈做的清炖鱼,奠定了清淡口味偏好。', recTry:'苏式清蒸鱼套餐(已上架二号食堂)',
|
||||
modelVer:'v2.3', modelTime:'2026-04-18', recCal:'1,650 kcal', nutriFocus:'钙+铁+维生素D', risk:'注意糖摄入', tags:'轻食主义、养生达人、低糖饮食', confidence:'95%', nextUpdate:'2026-05-28' }
|
||||
};
|
||||
const defaultProfile = { dept:'—', age:30, gender:'—', height:'170cm', weight:'65kg', bmi:'22.5', activity:'中等',
|
||||
disease:'无', chronic:'无', medicine:'无', family:'无',
|
||||
examDate:'2026-01-10', bp:'120/78', glucose:'5.0', lipid:'正常', uric:'350', liver:'正常', kidney:'正常',
|
||||
taste:'适中', region:'不限', taboo:'无', allergy:'无',
|
||||
exercise:'5000步/日', weightTrend:'稳定', bodyFat:'20%', heartRate:'70', sleep:'7h', stress:'低', source:'手动录入',
|
||||
meals30:'45次', hotDish:'家常菜', avgCal:'600kcal', nutriRate:'78%',
|
||||
favDish:'红烧肉、西红柿炒蛋', recDish:'杂粮饭套餐', avoidDish:'无', topRate:'红烧肉(4.5)', repurchase:'西红柿炒蛋',
|
||||
hometown:'—', momTag:'家常味', momList:'红烧肉', memory:'—', recTry:'—',
|
||||
modelVer:'v2.3', modelTime:'2026-04-15', recCal:'1900kcal', nutriFocus:'均衡', risk:'无', tags:'普通用户', confidence:'80%' };
|
||||
meals30:'45次', hotDish:'家常菜', avgCal:'1,900 kcal/天', nutriRate:'78%',
|
||||
proteinRate:'80%', highFatRate:'12%', preferMeal:'午餐', lastMeal:'2026-04-28 午餐',
|
||||
mealHistory:[
|
||||
{date:'2026-04-28',meal:'午餐',dishes:'红烧肉、米饭、炒青菜、蛋花汤',cal:'856 kcal',score:82},
|
||||
{date:'2026-04-27',meal:'午餐',dishes:'西红柿炒蛋、米饭、紫菜汤',cal:'720 kcal',score:85},
|
||||
{date:'2026-04-26',meal:'午餐',dishes:'糖醋里脊、米饭、炒时蔬',cal:'880 kcal',score:80},
|
||||
{date:'2026-04-25',meal:'午餐',dishes:'红烧肉、杂粮饭、凉拌黄瓜',cal:'810 kcal',score:84},
|
||||
{date:'2026-04-24',meal:'午餐',dishes:'宫保鸡丁、米饭、番茄蛋汤',cal:'790 kcal',score:86}
|
||||
],
|
||||
favDish:'红烧肉、西红柿炒蛋、炒青菜', recDish:'杂粮饭套餐、蒸南瓜', avoidDish:'暂无', topRate:'红烧肉(90分)', repurchase:'西红柿炒蛋(近30日15次)',
|
||||
hometown:'—', momTag:'家常、咸鲜、炖煮', momList:'红烧肉、炖排骨、西红柿炒蛋', memory:'小时候最爱妈妈做的红烧肉,是家的味道。', recTry:'家常红烧肉套餐(已上架一号食堂)',
|
||||
modelVer:'v2.3', modelTime:'2026-04-15', recCal:'1,900 kcal', nutriFocus:'均衡', risk:'无风险', tags:'家常口味、中度活动、无慢病', confidence:'80%', nextUpdate:'2026-05-28' };
|
||||
|
||||
const tabDefs = [
|
||||
{ key:'basic', label:'静态基础' },{ key:'disease', label:'疾病信息' },{ key:'physical', label:'体检信息' },
|
||||
@@ -606,16 +757,95 @@ const tabDefs = [
|
||||
|
||||
function buildProfileHTML(name, p) {
|
||||
const panels = {
|
||||
basic: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">姓名</span><span class="profile-field__value">${name}</span></div><div class="profile-field"><span class="profile-field__label">部门</span><span class="profile-field__value">${p.dept}</span></div><div class="profile-field"><span class="profile-field__label">年龄</span><span class="profile-field__value">${p.age}岁</span></div><div class="profile-field"><span class="profile-field__label">性别</span><span class="profile-field__value">${p.gender}</span></div><div class="profile-field"><span class="profile-field__label">身高</span><span class="profile-field__value">${p.height}</span></div><div class="profile-field"><span class="profile-field__label">体重</span><span class="profile-field__value">${p.weight}</span></div><div class="profile-field"><span class="profile-field__label">BMI</span><span class="profile-field__value">${p.bmi}</span></div><div class="profile-field"><span class="profile-field__label">活动水平</span><span class="profile-field__value">${p.activity}</span></div></div>`,
|
||||
disease: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">疾病史</span><span class="profile-field__value">${p.disease}</span></div><div class="profile-field"><span class="profile-field__label">慢病分级</span><span class="profile-field__value">${p.chronic}</span></div><div class="profile-field"><span class="profile-field__label">用药情况</span><span class="profile-field__value">${p.medicine}</span></div><div class="profile-field"><span class="profile-field__label">家族病史</span><span class="profile-field__value">${p.family}</span></div></div>`,
|
||||
physical: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">体检日期</span><span class="profile-field__value">${p.examDate}</span></div><div class="profile-field"><span class="profile-field__label">血压</span><span class="profile-field__value">${p.bp} mmHg</span></div><div class="profile-field"><span class="profile-field__label">空腹血糖</span><span class="profile-field__value">${p.glucose} mmol/L</span></div><div class="profile-field"><span class="profile-field__label">血脂</span><span class="profile-field__value">${p.lipid}</span></div><div class="profile-field"><span class="profile-field__label">尿酸</span><span class="profile-field__value">${p.uric} μmol/L</span></div><div class="profile-field"><span class="profile-field__label">肝功能</span><span class="profile-field__value">${p.liver}</span></div><div class="profile-field"><span class="profile-field__label">肾功能</span><span class="profile-field__value">${p.kidney}</span></div></div>`,
|
||||
taste: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">口味偏好</span><span class="profile-field__value">${p.taste}</span></div><div class="profile-field"><span class="profile-field__label">地域菜系</span><span class="profile-field__value">${p.region}</span></div></div>`,
|
||||
taboo: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">饮食禁忌</span><span class="profile-field__value">${p.taboo}</span></div><div class="profile-field"><span class="profile-field__label">过敏原</span><span class="profile-field__value">${p.allergy}</span></div></div>`,
|
||||
dynamic: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">日均运动量</span><span class="profile-field__value">${p.exercise}</span></div><div class="profile-field"><span class="profile-field__label">体重趋势</span><span class="profile-field__value">${p.weightTrend}</span></div><div class="profile-field"><span class="profile-field__label">体脂率</span><span class="profile-field__value">${p.bodyFat}</span></div><div class="profile-field"><span class="profile-field__label">静息心率</span><span class="profile-field__value">${p.heartRate} bpm</span></div><div class="profile-field"><span class="profile-field__label">平均睡眠</span><span class="profile-field__value">${p.sleep}</span></div><div class="profile-field"><span class="profile-field__label">压力指数</span><span class="profile-field__value">${p.stress}</span></div><div class="profile-field"><span class="profile-field__label">数据来源</span><span class="profile-field__value">${p.source}</span></div></div>`,
|
||||
meal: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">近30日就餐</span><span class="profile-field__value">${p.meals30}</span></div><div class="profile-field"><span class="profile-field__label">常点菜品</span><span class="profile-field__value">${p.hotDish}</span></div><div class="profile-field"><span class="profile-field__label">平均热量</span><span class="profile-field__value">${p.avgCal}</span></div><div class="profile-field"><span class="profile-field__label">营养达标率</span><span class="profile-field__value">${p.nutriRate}</span></div></div>`,
|
||||
dish: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">常点菜品</span><span class="profile-field__value">${p.favDish}</span></div><div class="profile-field"><span class="profile-field__label">系统推荐</span><span class="profile-field__value">${p.recDish}</span></div><div class="profile-field"><span class="profile-field__label">忌口菜品</span><span class="profile-field__value">${p.avoidDish}</span></div><div class="profile-field"><span class="profile-field__label">评分最高</span><span class="profile-field__value">${p.topRate}</span></div><div class="profile-field"><span class="profile-field__label">复购冠军</span><span class="profile-field__value">${p.repurchase}</span></div></div>`,
|
||||
mom: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">家乡</span><span class="profile-field__value">${p.hometown}</span></div><div class="profile-field"><span class="profile-field__label">妈妈味道标签</span><span class="profile-field__value">${p.momTag}</span></div><div class="profile-field"><span class="profile-field__label">思乡菜清单</span><span class="profile-field__value">${p.momList}</span></div><div class="profile-field"><span class="profile-field__label">关联记忆</span><span class="profile-field__value">${p.memory}</span></div><div class="profile-field"><span class="profile-field__label">推荐尝试</span><span class="profile-field__value">${p.recTry}</span></div></div>`,
|
||||
model: `<div class="profile-grid"><div class="profile-field"><span class="profile-field__label">模型版本</span><span class="profile-field__value">${p.modelVer}</span></div><div class="profile-field"><span class="profile-field__label">生成时间</span><span class="profile-field__value">${p.modelTime}</span></div><div class="profile-field"><span class="profile-field__label">推荐热量</span><span class="profile-field__value">${p.recCal}</span></div><div class="profile-field"><span class="profile-field__label">营养侧重</span><span class="profile-field__value">${p.nutriFocus}</span></div><div class="profile-field"><span class="profile-field__label">风险预警</span><span class="profile-field__value">${p.risk}</span></div><div class="profile-field"><span class="profile-field__label">个性标签</span><span class="profile-field__value">${p.tags}</span></div><div class="profile-field"><span class="profile-field__label">模型置信度</span><span class="profile-field__value">${p.confidence}</span></div></div>`
|
||||
basic: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">姓名</span><span class="profile-field__value">${name}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">部门</span><span class="profile-field__value">${p.dept}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">年龄</span><span class="profile-field__value">${p.age}岁</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">性别</span><span class="profile-field__value">${p.gender}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">身高</span><span class="profile-field__value">${p.height}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">体重</span><span class="profile-field__value">${p.weight}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">BMI</span><span class="profile-field__value">${p.bmi}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">活动水平</span><span class="profile-field__value">${p.activity}</span></div>
|
||||
</div>`,
|
||||
disease: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">疾病史</span><span class="profile-field__value">${p.disease}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">慢病分级</span><span class="profile-field__value">${p.chronic}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">用药情况</span><span class="profile-field__value">${p.medicine}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">家族病史</span><span class="profile-field__value">${p.family}</span></div>
|
||||
</div>`,
|
||||
physical: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">体检日期</span><span class="profile-field__value">${p.examDate}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">血压</span><span class="profile-field__value">${p.bp} mmHg</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">空腹血糖</span><span class="profile-field__value">${p.glucose} mmol/L</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">血脂</span><span class="profile-field__value">${p.lipid}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">尿酸</span><span class="profile-field__value">${p.uric} μmol/L</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">肝功能</span><span class="profile-field__value">${p.liver}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">肾功能</span><span class="profile-field__value">${p.kidney}</span></div>
|
||||
</div>`,
|
||||
taste: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">口味偏好</span><span class="profile-field__value">${p.taste}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">地域菜系</span><span class="profile-field__value">${p.region}</span></div>
|
||||
</div>`,
|
||||
taboo: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">饮食禁忌</span><span class="profile-field__value">${p.taboo}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">过敏原</span><span class="profile-field__value">${p.allergy}</span></div>
|
||||
</div>`,
|
||||
dynamic: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">日均运动量</span><span class="profile-field__value">${p.exercise}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">体重趋势</span><span class="profile-field__value">${p.weightTrend}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">体脂率</span><span class="profile-field__value">${p.bodyFat}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">静息心率</span><span class="profile-field__value">${p.heartRate} bpm</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">平均睡眠</span><span class="profile-field__value">${p.sleep}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">压力指数</span><span class="profile-field__value">${p.stress}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">数据来源</span><span class="profile-field__value">${p.source}</span></div>
|
||||
</div>`,
|
||||
meal: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">近30日就餐次数</span><span class="profile-field__value">${p.meals30}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">最常点菜品</span><span class="profile-field__value">${p.hotDish}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">平均热量摄入</span><span class="profile-field__value">${p.avgCal}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">蛋白质达标率</span><span class="profile-field__value">${p.proteinRate}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">高脂餐占比</span><span class="profile-field__value">${p.highFatRate}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">偏好餐次</span><span class="profile-field__value">${p.preferMeal}</span></div>
|
||||
</div>
|
||||
<div class="profile-field" style="border-bottom:none;padding:12px 0 4px;"><span class="profile-field__label">最近一次就餐</span><span class="profile-field__value">${p.lastMeal}</span></div>
|
||||
<div style="margin-top:16px;font-size:var(--font-sm);font-weight:600;color:var(--text-primary);margin-bottom:10px;">📋 最近用餐明细(${p.mealHistory.length}条)</div>
|
||||
<table class="meal-history-table">
|
||||
<thead><tr><th>日期</th><th>餐次</th><th>菜品</th><th>热量</th><th>营养评分</th></tr></thead>
|
||||
<tbody>${p.mealHistory.map(h => '<tr><td>'+h.date+'</td><td><span class="tag tag-blue">'+h.meal+'</span></td><td>'+h.dishes+'</td><td>'+h.cal+'</td><td><span class="score-tag'+(h.score>=85?' score-green':' score-orange')+'">'+h.score+'分</span></td></tr>').join('')}</tbody>
|
||||
</table>`,
|
||||
dish: `<div class="dish-pref-section">
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">常点菜品</div><div class="dish-pref-item__tags">${p.favDish.split('、').map(d=>'<span class="dish-tag">'+d+'</span>').join('')}</div></div>
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">系统推荐</div><div class="dish-pref-item__tags">${p.recDish.split('、').map(d=>'<span class="dish-tag">'+d+'</span>').join('')}</div></div>
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">忌口菜品</div><div class="dish-pref-item__value">${p.avoidDish||'暂无'}</div></div>
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">评分最高</div><div class="dish-pref-item__big">${p.topRate}</div></div>
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">复购冠军</div><div class="dish-pref-item__big">${p.repurchase}</div></div>
|
||||
</div>`,
|
||||
mom: `<div class="mom-section">
|
||||
<div class="mom-header">
|
||||
<div class="mom-header__icon">🐱</div>
|
||||
<div class="mom-header__info"><div class="mom-header__title">家乡:${p.hometown}</div><div class="mom-header__sub">从童年记忆中沉淀的味觉偏好与情感连接</div></div>
|
||||
</div>
|
||||
<div class="mom-header__tags">${p.momTag.split('、').map(t=>'<span class="mom-tag">'+t+'</span>').join('')}</div>
|
||||
</div>
|
||||
<div class="dish-pref-section" style="margin-top:20px;">
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">思乡菜清单</div><div class="dish-pref-item__tags">${p.momList.split('、').map(d=>'<span class="dish-tag" style="color:#FA8C16;background:#FFF7E6;border-color:#FFD591;">'+d+'</span>').join('')}</div></div>
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">关联记忆</div><div class="dish-pref-item__value" style="margin-top:4px;">${p.memory}</div></div>
|
||||
<div class="dish-pref-item"><div class="dish-pref-item__label">推荐尝试</div><div class="dish-pref-item__value" style="color:#52C41A;font-weight:600;margin-top:4px;">${p.recTry}</div></div>
|
||||
</div>`,
|
||||
model: `<div class="model-section">
|
||||
<div class="model-header">
|
||||
<div class="model-header__icon">🤖</div>
|
||||
<div class="model-header__info"><div class="model-header__title">${name} 的个性化营养模型</div><div class="model-header__sub">${p.modelVer} · 生成于 ${p.modelTime} · 置信度 ${p.confidence}</div></div>
|
||||
</div>
|
||||
<div class="model-header__tags">${p.tags.split('、').map(t=>'<span class="model-tag">'+t+'</span>').join('')}</div>
|
||||
</div>
|
||||
<div class="model-grid">
|
||||
<div class="model-item"><div class="model-item__label">推荐每日热量</div><div class="model-item__big">${p.recCal}</div></div>
|
||||
<div class="model-item"><div class="model-item__label">营养侧重</div><div class="model-item__big">${p.nutriFocus}</div></div>
|
||||
<div class="model-item"><div class="model-item__label">风险预警</div><div class="model-item__value"><span class="risk-tag${p.risk==='无风险'?' risk-safe':' risk-warn'}">${p.risk==='无风险'?'✅ ':''} ${p.risk}</span></div></div>
|
||||
<div class="model-item"><div class="model-item__label">下次模型更新</div><div class="model-item__big">${p.nextUpdate}</div></div>
|
||||
</div>
|
||||
<div class="model-footer">ℹ️ 个性模型由前9维档案数据综合计算生成(含菜品偏好、妈妈味道等情感维度),每月自动更新一次</div>`
|
||||
};
|
||||
const tabs = tabDefs.map((t, i) => `<div class="profile-tab${i===0?' active':''}" onclick="switchProfileTab(this,'${t.key}')">${t.label}</div>`).join('');
|
||||
const panelsHtml = tabDefs.map((t, i) => `<div class="profile-panel${i===0?' active':''}" data-panel="${t.key}">${panels[t.key]}</div>`).join('');
|
||||
@@ -778,16 +1008,10 @@ function showNutriDetail() {
|
||||
function buildDishDetailHTML() {
|
||||
const headerInfo = `<div class="dish-header-info">
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">用户:</span><span class="dish-header-info__value">张伟(EMP001)</span></div>
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">统计范围:</span><span class="dish-header-info__value">2026-04-28 午餐</span></div>
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">消费合计:</span><span class="dish-header-info__value" style="color:var(--primary);font-weight:700;">¥22.00</span></div>
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">营养评分:</span><span class="tag tag-green">88分</span></div>
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">日期:</span><span class="dish-header-info__value">2026-04-28</span></div>
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">餐次:</span><span class="dish-header-info__value">午餐</span></div>
|
||||
<div class="dish-header-info__item"><span class="dish-header-info__label">来源:</span><span class="dish-header-info__value">点餐</span></div>
|
||||
</div>`;
|
||||
|
||||
const tip = `<div class="dish-tip">
|
||||
<svg width="14" height="14" viewBox="0 0 16 16" fill="none"><circle cx="8" cy="8" r="7" stroke="currentColor" stroke-width="1.5"/><path d="M8 4.5v4M8 10.5v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>
|
||||
点击「食材溯源链路」按钮可在链路可视化中查看该餐品对应的食材溯源链路
|
||||
</div>`;
|
||||
|
||||
const table = `<table class="dish-table">
|
||||
<thead><tr><th>餐品编码</th><th>菜品</th><th>重量</th><th>热量(kcal)</th><th>蛋白质</th><th>碳水</th><th>脂肪</th><th>钠</th><th>单价</th><th>超标状态</th><th>食材溯源</th></tr></thead>
|
||||
<tbody>
|
||||
@@ -796,33 +1020,39 @@ function buildDishDetailHTML() {
|
||||
<tr><td class="td-code">DM-CSHU</td><td>炒时蔬</td><td>80g</td><td>38</td><td>2.1g</td><td>5.2g</td><td>1.2g</td><td>180mg</td><td>¥8.00</td><td><span class="tag tag-green">正常</span></td><td><a class="dish-trace-link">🔗 食材溯源链路</a></td></tr>
|
||||
</tbody>
|
||||
</table>`;
|
||||
|
||||
const summary = `<div class="dish-summary">
|
||||
<div class="dish-summary__item"><span class="dish-summary__label">总热量:</span><span class="dish-summary__value blue">856 kcal</span></div>
|
||||
<div class="dish-summary__item"><span class="dish-summary__label">热量达成率:</span><span class="dish-summary__value orange">43%</span></div>
|
||||
<div class="dish-summary__item"><span class="dish-summary__label">消费合计:</span><span class="dish-summary__value">¥22.00</span></div>
|
||||
<div class="dish-summary__item"><span class="dish-summary__label">营养评分:</span><span class="dish-summary__value green">88分</span></div>
|
||||
</div>`;
|
||||
|
||||
return headerInfo + tip + table + summary;
|
||||
const tip = `<div class="dish-tip">
|
||||
<svg width="14" height="14" viewBox="0 0 14 14" fill="none"><circle cx="7" cy="7" r="6" stroke="currentColor" stroke-width="1.2"/><path d="M7 4v3M7 9v.5" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>
|
||||
点击"食材溯源链路"可查看该菜品从采购到出餐的完整追溯信息
|
||||
</div>`;
|
||||
return headerInfo + table + summary + tip;
|
||||
}
|
||||
|
||||
function showDishDetail() {
|
||||
Modal.open('溯源关联 — 张伟(EMP001) · 2026-04-28 午餐', buildDishDetailHTML(), 'dish-modal');
|
||||
Modal.open('餐品明细 — 张伟(EMP001) · 2026-04-28 午餐', buildDishDetailHTML(), 'dish-modal');
|
||||
}
|
||||
|
||||
/* ========== 营养师工作台弹窗 ========== */
|
||||
const wbData = {
|
||||
user:'张伟(EMP001)', dept:'研发部', personType:'会员', age:38, gender:'男', bmi:'22.9', diseaseLabel:'无',
|
||||
user:'张伟(EMP001)', dept:'采油一厂/研发部', personType:'会员', age:38, gender:'男', bmi:'22.9', diseaseLabel:'无',
|
||||
avgScore30:86, riskLevel:'低', interventionStatus:'已稳定', nutritionist:'林营养师', lastFollowUp:'2026-04-26',
|
||||
scoreTrend:[82,84,85,86,88,87,86],
|
||||
warnings:[],
|
||||
warnings:[
|
||||
{ type:'钠摄入超标', severity:'高', evidence:'近7日钠摄入均值达 3200mg/日,超出推荐上限(2000mg)60%。合并高血压病史,需立即干预。', triggeredAt:'2026-05-18 09:15', notified:true },
|
||||
{ type:'脂肪比例偏高', severity:'中', evidence:'近14日脂肪供能比达 38%,超出推荐范围(20%~30%)。建议减少油炸食品和红肉摄入。', triggeredAt:'2026-05-16 14:30', notified:true },
|
||||
{ type:'蛋白质摄入不足', severity:'低', evidence:'近7日蛋白质日均摄入 42g,低于推荐值(65g)。建议增加优质蛋白(鱼、蛋、豆制品)。', triggeredAt:'2026-05-20 10:00', notified:false }
|
||||
],
|
||||
plans:[
|
||||
{ goal:'维持当前营养均衡水平', period:'2026-04-01 ~ 2026-09-30', progress:65, items:['每日蛋白质保持 ≥75g','深色蔬菜每日 ≥250g','红肉每周 ≤3 次'], status:'进行中' }
|
||||
],
|
||||
advices:[
|
||||
{ time:'2026-04-26', author:'林营养师', content:'本月各项指标稳定,继续保持当前饮食结构。下次复评 2026-05-26。', isAi:false },
|
||||
{ time:'2026-04-15', author:'AI 助手', content:'检测到脂肪摄入连续 3 日偏高,建议减少红肉频次。', isAi:true }
|
||||
{ time:'2026-04-26 12:23', author:'林营养师', content:'本月各项指标稳定,继续保持当前饮食结构。下次复评 2026-05-26。', isAi:false },
|
||||
{ time:'2026-04-15 12:23', author:'林营养师', content:'检测到脂肪摄入连续 3 日偏高,建议减少红肉频次。', isAi:false }
|
||||
],
|
||||
followUps:[
|
||||
{ time:'2026-04-26 14:30', who:'林营养师', topic:'月度复评', content:'电话沟通,用户反馈饮食习惯无变化,BMI 维持 22.9。', feedback:'满意' },
|
||||
@@ -867,8 +1097,8 @@ function buildWorkbenchHTML() {
|
||||
<div><div class="wb-info-item__label">BMI</div><div class="wb-info-item__value">${a.bmi}</div></div>
|
||||
<div><div class="wb-info-item__label">慢病标签</div><div class="wb-info-item__value" style="color:${a.diseaseLabel === '无' ? '#52C41A' : '#FF4D4F'}">${a.diseaseLabel}</div></div>
|
||||
<div><div class="wb-info-item__label">人员类别</div><div class="wb-info-item__value">${a.personType}</div></div>
|
||||
<div><div class="wb-info-item__label">负责营养师</div><div class="wb-info-item__value" style="color:var(--primary)">${a.nutritionist}</div></div>
|
||||
<div><div class="wb-info-item__label">最近跟进</div><div class="wb-info-item__value">${a.lastFollowUp}</div></div>
|
||||
<div><div class="wb-info-item__label">最近跟进时间</div><div class="wb-info-item__value">${a.lastFollowUp}</div></div>
|
||||
<div><div class="wb-info-item__label">跟进营养师</div><div class="wb-info-item__value" style="color:var(--primary)">${a.nutritionist}</div></div>
|
||||
<div><div class="wb-info-item__label">干预状态</div><div class="wb-info-item__value">${a.interventionStatus}</div></div>
|
||||
</div>
|
||||
</div>`;
|
||||
@@ -885,20 +1115,27 @@ function buildWorkbenchHTML() {
|
||||
</div>`;
|
||||
}).join('')
|
||||
: '<div class="wb-empty"><div class="wb-empty__icon">✅</div>当前无疾病预警</div>';
|
||||
const warnHtml = `<div class="wb-panel-bar"><div class="wb-panel-bar__title">预警列表(${a.warnings.length})</div><button class="btn btn-primary" style="height:28px;font-size:12px;padding:0 10px;" onclick="alert('已添加预警(原型演示)')">+ 新增预警</button></div>${warnList}`;
|
||||
const warnHtml = `<div class="wb-panel-bar"><div class="wb-panel-bar__title">预警列表(${a.warnings.length})</div><button class="btn btn-primary" style="height:28px;font-size:12px;padding:0 10px;" onclick="showAddWarning()">+ 新增预警</button></div>${warnList}`;
|
||||
|
||||
/* ② 营养规划 */
|
||||
const planList = a.plans.length
|
||||
? a.plans.map(p => `<div class="wb-plan">
|
||||
<div class="wb-plan__head"><span class="wb-plan__goal">🎯 ${p.goal}</span><span class="tag tag-blue">${p.status}</span></div>
|
||||
? a.plans.map((p, pi) => {
|
||||
const isClosed = p.status === '已结束';
|
||||
const editBtn = isClosed ? '' : `<button class="btn btn-default" style="height:26px;font-size:11px;padding:0 8px;" onclick="showEditPlan(${pi})">编辑</button>`;
|
||||
const closeBtn = isClosed ? '' : `<button class="btn btn-default" style="height:26px;font-size:11px;padding:0 8px;" onclick="confirmClosePlan(this)">结案</button>`;
|
||||
const delBtn = `<button class="btn btn-default" style="height:26px;font-size:11px;padding:0 8px;color:var(--danger);border-color:#ffa39e;" onclick="confirmDeletePlan(this)">删除</button>`;
|
||||
const tagCls = isClosed ? 'tag-gray' : 'tag-blue';
|
||||
return `<div class="wb-plan">
|
||||
<div class="wb-plan__head"><span class="wb-plan__goal">🎯 ${p.goal}</span><span class="tag ${tagCls}">${p.status}</span></div>
|
||||
<div class="wb-plan__period">⏱ ${p.period}</div>
|
||||
<div class="wb-plan__bar"><div class="wb-plan__bar-fill" style="width:${p.progress}%"></div></div>
|
||||
<div class="wb-plan__pct">完成进度 <strong style="color:var(--primary)">${p.progress}%</strong></div>
|
||||
<div class="wb-plan__items">${p.items.map(i => `<div>· ${i}</div>`).join('')}</div>
|
||||
<div class="wb-plan__actions"><button class="btn btn-default" style="height:26px;font-size:11px;padding:0 8px;" onclick="alert('编辑规划(原型演示)')">编辑</button><button class="btn btn-default" style="height:26px;font-size:11px;padding:0 8px;" onclick="alert('已结案(原型演示)')">结案</button></div>
|
||||
</div>`).join('')
|
||||
<div class="wb-plan__actions">${editBtn}${closeBtn}${delBtn}</div>
|
||||
</div>`;
|
||||
}).join('')
|
||||
: '<div class="wb-empty"><div class="wb-empty__icon">📋</div>暂无营养规划</div>';
|
||||
const planHtml = `<div class="wb-panel-bar"><div class="wb-panel-bar__title">营养规划(${a.plans.length})</div><button class="btn btn-primary" style="height:28px;font-size:12px;padding:0 10px;" onclick="alert('已创建规划(原型演示)')">+ 新建规划</button></div>${planList}`;
|
||||
const planHtml = `<div class="wb-panel-bar"><div class="wb-panel-bar__title">营养规划(${a.plans.length})</div><button class="btn btn-primary" style="height:28px;font-size:12px;padding:0 10px;" onclick="showAddPlan()">+ 新建规划</button></div>${planList}`;
|
||||
|
||||
/* ③ 营养建议 */
|
||||
const advList = a.advices.map(ad => {
|
||||
@@ -924,7 +1161,7 @@ function buildWorkbenchHTML() {
|
||||
</div>
|
||||
</div>`).join('')}</div>`
|
||||
: '<div class="wb-empty">暂无跟进记录</div>';
|
||||
const followHtml = `<div class="wb-panel-bar"><div class="wb-panel-bar__title">跟进时间轴(${a.followUps.length})</div><button class="btn btn-primary" style="height:28px;font-size:12px;padding:0 10px;" onclick="alert('已添加跟进记录(原型演示)')">+ 新建跟进</button></div>${followList}`;
|
||||
const followHtml = `<div class="wb-panel-bar"><div class="wb-panel-bar__title">跟进时间轴(${a.followUps.length})</div><button class="btn btn-primary" style="height:28px;font-size:12px;padding:0 10px;" onclick="showAddFollowUp()">+ 新建跟进</button></div>${followList}`;
|
||||
|
||||
/* 右侧面板 */
|
||||
const right = `<div class="wb-right">
|
||||
@@ -955,11 +1192,204 @@ function showWorkbench() {
|
||||
Modal.open('🍽️ 营养师工作台 — ' + wbData.user, buildWorkbenchHTML(), 'wb-modal', footer);
|
||||
}
|
||||
|
||||
/* ========== 新增预警弹窗(叠层) ========== */
|
||||
function showAddWarning() {
|
||||
const html = `<div class="wb-form">
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">预警标题</label>
|
||||
<div class="wb-form-row__body">
|
||||
<input class="wb-form-input" placeholder="如:钠摄入超标、脂肪比例偏高">
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">严重程度</label>
|
||||
<div class="wb-form-row__body">
|
||||
<div class="wb-form-radio-group">
|
||||
<label class="wb-form-radio"><input type="radio" name="warnSev" value="高"> <span class="tag tag-red" style="font-size:11px">高风险</span></label>
|
||||
<label class="wb-form-radio"><input type="radio" name="warnSev" value="中" checked> <span class="tag tag-orange" style="font-size:11px">中风险</span></label>
|
||||
<label class="wb-form-radio"><input type="radio" name="warnSev" value="低"> <span class="tag tag-blue" style="font-size:11px">低风险</span></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">预警依据</label>
|
||||
<div class="wb-form-row__body">
|
||||
<textarea class="wb-form-textarea" placeholder="请描述预警的数据依据,如:近7日钠摄入均值达 3200mg/日,超出推荐上限60%"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label">关联指标</label>
|
||||
<div class="wb-form-row__body">
|
||||
<div class="wb-form-checkbox-group">
|
||||
<label class="wb-form-checkbox"><input type="checkbox" checked> 热量(kcal)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox" checked> 钠(mg)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox"> 蛋白质(g)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox"> 脂肪(g)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox"> 碳水化合物(g)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox"> 胆固醇(mg)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox"> 膳食纤维(g)</label>
|
||||
<label class="wb-form-checkbox"><input type="checkbox"> BMI</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
const footer = `<button class="btn btn-default" onclick="Modal.closeLayer()">取消</button><button class="btn btn-primary" onclick="alert('预警已添加(原型演示)');Modal.closeLayer()">确认添加</button>`;
|
||||
Modal.openLayer('新增预警 — ' + wbData.user, html, 'wb-form-modal', footer);
|
||||
}
|
||||
|
||||
/* ========== 新建/编辑规划弹窗(叠层) ========== */
|
||||
function showAddPlan(editData) {
|
||||
const isEdit = !!editData;
|
||||
const goal = isEdit ? editData.goal : '';
|
||||
const dateStart = isEdit ? editData.period.split(' ~ ')[0] : '2026-05-21';
|
||||
const dateEnd = isEdit ? editData.period.split(' ~ ')[1] : '2026-08-21';
|
||||
const items = isEdit ? editData.items.join('\n') : '';
|
||||
const progress = isEdit ? editData.progress : 0;
|
||||
const html = `<div class="wb-form">
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">规划目标</label>
|
||||
<div class="wb-form-row__body">
|
||||
<input class="wb-form-input" value="${goal}" placeholder="如:降低钠摄入至推荐范围内">
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">规划周期</label>
|
||||
<div class="wb-form-row__body">
|
||||
<div class="wb-form-date-range">
|
||||
<input type="date" class="wb-form-input wb-form-date" value="${dateStart}">
|
||||
<span>至</span>
|
||||
<input type="date" class="wb-form-input wb-form-date" value="${dateEnd}">
|
||||
</div>
|
||||
<div class="wb-form-hint">建议周期 1~6 个月,到期可续期或结案</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">具体措施</label>
|
||||
<div class="wb-form-row__body">
|
||||
<textarea class="wb-form-textarea" rows="4" placeholder="如: 每日钠摄入 ≤2000mg 减少腌制食品频次至每周 ≤1 次 每餐增加蔬菜至 200g 以上">${items}</textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label">关联预警</label>
|
||||
<div class="wb-form-row__body">
|
||||
<select class="wb-form-select">
|
||||
<option value="">不关联</option>
|
||||
<option>钠摄入超标(高风险 · 2026-05-18)</option>
|
||||
<option>脂肪比例偏高(中风险 · 2026-05-16)</option>
|
||||
<option>蛋白质摄入不足(低风险 · 2026-05-20)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label">当前进度</label>
|
||||
<div class="wb-form-row__body">
|
||||
<div style="display:flex;align-items:center;gap:10px;">
|
||||
<input type="range" min="0" max="100" value="${progress}" style="flex:1" oninput="this.nextElementSibling.textContent=this.value+'%'">
|
||||
<span style="font-size:var(--font-sm);color:var(--primary);font-weight:600;min-width:36px">${progress}%</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
const btnText = isEdit ? '保存修改' : '创建规划';
|
||||
const title = isEdit ? '编辑营养规划 — ' + wbData.user : '新建营养规划 — ' + wbData.user;
|
||||
const footer = `<button class="btn btn-default" onclick="Modal.closeLayer()">取消</button><button class="btn btn-primary" onclick="alert('${isEdit ? '规划已更新' : '规划已创建'}(原型演示)');Modal.closeLayer()">${btnText}</button>`;
|
||||
Modal.openLayer(title, html, 'wb-form-modal', footer);
|
||||
}
|
||||
|
||||
function showEditPlan(idx) {
|
||||
showAddPlan(wbData.plans[idx]);
|
||||
}
|
||||
|
||||
function confirmClosePlan(btn) {
|
||||
if (confirm('是否结束此次营养规划?')) {
|
||||
var plan = btn.closest('.wb-plan');
|
||||
var tag = plan.querySelector('.tag');
|
||||
if (tag) { tag.textContent = '已结束'; tag.className = 'tag tag-gray'; }
|
||||
var bar = plan.querySelector('.wb-plan__bar-fill');
|
||||
if (bar) bar.style.width = '100%';
|
||||
var pct = plan.querySelector('.wb-plan__pct strong');
|
||||
if (pct) pct.textContent = '100%';
|
||||
/* 移除编辑和结案按钮,保留删除 */
|
||||
var editBtn = plan.querySelector('.wb-plan__actions button:first-child');
|
||||
if (editBtn && editBtn.textContent === '编辑') editBtn.remove();
|
||||
btn.remove();
|
||||
}
|
||||
}
|
||||
|
||||
function confirmDeletePlan(btn) {
|
||||
if (confirm('确定删除此营养规划?删除后不可恢复。')) {
|
||||
btn.closest('.wb-plan').remove();
|
||||
}
|
||||
}
|
||||
|
||||
/* ========== 新建跟进弹窗 ========== */
|
||||
function showAddFollowUp() {
|
||||
const html = `<div class="wb-form">
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">跟进主题</label>
|
||||
<div class="wb-form-row__body">
|
||||
<select class="wb-form-select">
|
||||
<option value="">请选择</option>
|
||||
<option>月度复评</option>
|
||||
<option>预警跟进</option>
|
||||
<option>规划检查</option>
|
||||
<option>饮食指导</option>
|
||||
<option>异常干预</option>
|
||||
<option>其他</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">跟进方式</label>
|
||||
<div class="wb-form-row__body">
|
||||
<div class="wb-form-radio-group">
|
||||
<label class="wb-form-radio"><input type="radio" name="fuMethod" value="电话" checked> 电话</label>
|
||||
<label class="wb-form-radio"><input type="radio" name="fuMethod" value="面谈"> 面谈</label>
|
||||
<label class="wb-form-radio"><input type="radio" name="fuMethod" value="线上"> 线上</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">跟进时间</label>
|
||||
<div class="wb-form-row__body">
|
||||
<input type="datetime-local" class="wb-form-input" style="width:220px" value="2026-05-21T14:00">
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label required">跟进内容</label>
|
||||
<div class="wb-form-row__body">
|
||||
<textarea class="wb-form-textarea" rows="4" placeholder="请记录本次跟进的沟通内容、发现的问题和给出的建议"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label">用户反馈</label>
|
||||
<div class="wb-form-row__body">
|
||||
<div class="wb-form-radio-group">
|
||||
<label class="wb-form-radio"><input type="radio" name="fuFb" value="满意"> 满意</label>
|
||||
<label class="wb-form-radio"><input type="radio" name="fuFb" value="认可" checked> 认可</label>
|
||||
<label class="wb-form-radio"><input type="radio" name="fuFb" value="一般"> 一般</label>
|
||||
<label class="wb-form-radio"><input type="radio" name="fuFb" value="不配合"> 不配合</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="wb-form-row">
|
||||
<label class="wb-form-row__label">下次跟进</label>
|
||||
<div class="wb-form-row__body">
|
||||
<input type="date" class="wb-form-input wb-form-date" value="请选择">
|
||||
<div class="wb-form-hint">设置后将在到期当天自动提醒</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
const footer = `<button class="btn btn-default" onclick="Modal.closeLayer()">取消</button><button class="btn btn-primary" onclick="alert('跟进记录已保存(原型演示)');Modal.closeLayer()">保存记录</button>`;
|
||||
Modal.openLayer('新建跟进记录 — ' + wbData.user, html, 'wb-form-modal', footer);
|
||||
}
|
||||
|
||||
/* ========== 四个 Tab 列表事件绑定 ========== */
|
||||
document.querySelectorAll('.tab-panel').forEach((panel, tabIdx) => {
|
||||
panel.querySelectorAll('tbody tr').forEach(row => {
|
||||
const links = row.querySelectorAll('.td-actions .link');
|
||||
const nameCell = row.querySelector('td:first-child');
|
||||
/* Tab0/1/2 姓名在第2列,Tab3 姓名在第1列 */
|
||||
const nameCell = tabIdx < 3 ? row.querySelector('td:nth-child(2)') : row.querySelector('td:first-child');
|
||||
if (!nameCell) return;
|
||||
const rawName = nameCell.textContent.trim();
|
||||
const userName = rawName.replace(/\(.*\)/, '').trim();
|
||||
|
||||
@@ -98,6 +98,17 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.log-table tbody td{padding:12px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);}
|
||||
.log-table tbody tr:last-child td{border-bottom:none;}
|
||||
.log-table tbody tr:hover{background:#F8FBFF;}
|
||||
/* 新增模型弹窗表单 */
|
||||
.add-form-row{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px;}
|
||||
.add-form-item{display:flex;flex-direction:column;gap:6px;}
|
||||
.add-form-item label{font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;}
|
||||
.add-form-item label .req{color:var(--danger);margin-left:2px;}
|
||||
.add-form-item input,.add-form-item select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;width:100%;}
|
||||
.add-form-item input:focus,.add-form-item select:focus{border-color:var(--primary);}
|
||||
.add-form-item select{padding-right:28px;appearance: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;cursor:pointer;}
|
||||
.add-form-item textarea{width:100%;border:1px solid var(--border);border-radius:var(--radius-sm);padding:8px 12px;font-size:var(--font-sm);outline:none;resize:vertical;min-height:60px;font-family:inherit;}
|
||||
.add-form-item textarea:focus{border-color:var(--primary);}
|
||||
.dyn-modal.model-modal{width:640px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -168,15 +179,15 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
<!-- 筛选栏 -->
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>模型名称</label><input class="filter-input" type="text" placeholder="请输入模型名称"></div>
|
||||
<div class="filter-item"><label>模型提供商</label><select class="filter-select"><option>全部</option><option>字节跳动</option><option>深度求索</option><option>百度</option></select></div>
|
||||
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>在用</option><option>备用</option></select></div>
|
||||
<div class="filter-item"><label>模型供应商</label><select class="filter-select"><option>全部</option><option>字节跳动</option><option>深度求索</option><option>百度</option></select></div>
|
||||
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>启用</option><option>停用</option></select></div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
</div>
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-primary">➕ 接入新模型</button>
|
||||
<button class="btn btn-primary" onclick="openAddModel()">➕ 接入新模型</button>
|
||||
</div>
|
||||
|
||||
<!-- 数据表格 -->
|
||||
@@ -186,11 +197,11 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>模型编号</th><th>模型名称</th><th>提供商</th><th>版本</th><th>接入方式</th><th>使用场景</th><th>月调用量(次)</th><th>月消耗Token</th><th>月费用</th><th>平均响应(ms)</th><th>错误率</th><th>超时率</th><th>状态</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>模型编号</th><th>模型名称</th><th>API_KEY</th><th>API_URL</th><th>供应商</th><th>版本</th><th>接入方式</th><th>使用场景</th><th>月调用量(次)</th><th>月消耗Token</th><th>月费用</th><th>平均响应(ms)</th><th>错误率</th><th>超时率</th><th>状态</th><th>操作</th></tr></thead>
|
||||
<tbody>
|
||||
<tr><td>LLM-001</td><td>豆包</td><td>字节跳动</td><td>Doubao-pro-32k</td><td>API调用</td><td>小程序AI营养顾问</td><td>68,240</td><td>42.6万</td><td>¥2,140</td><td>320</td><td>0.12%</td><td>0.08%</td><td><span class="tag tag-green">在用</span></td><td class="td-actions"><a class="link">调试日志</a></td></tr>
|
||||
<tr><td>LLM-002</td><td>DeepSeek-V3</td><td>深度求索</td><td>v3-20250324</td><td>API调用</td><td>管理端智能助手</td><td>54,820</td><td>38.2万</td><td>¥1,720</td><td>280</td><td>0.08%</td><td>0.05%</td><td><span class="tag tag-green">在用</span></td><td class="td-actions"><a class="link">调试日志</a></td></tr>
|
||||
<tr><td>LLM-003</td><td>文心一言</td><td>百度</td><td>ERNIE-4.0</td><td>API调用</td><td>小程序AI营养顾问</td><td>0</td><td>0</td><td>¥0</td><td>—</td><td>—</td><td>—</td><td><span class="tag tag-orange">备用</span></td><td class="td-actions"><a class="link">调试日志</a></td></tr>
|
||||
<tr><td>LLM-001</td><td>豆包</td><td>sk-****8a3f</td><td>https://api.doubao.com/v1</td><td>字节跳动</td><td>Doubao-pro-32k</td><td>API调用</td><td>小程序AI营养顾问</td><td>68,240</td><td>42.6万</td><td>¥2,140</td><td>320</td><td>0.12%</td><td>0.08%</td><td><span class="tag tag-green">启用</span></td><td class="td-actions"><a class="link">编辑</a> <a class="link">调试日志</a></td></tr>
|
||||
<tr><td>LLM-002</td><td>DeepSeek-V3</td><td>sk-****d2e1</td><td>https://api.deepseek.com/v1</td><td>深度求索</td><td>v3-20250324</td><td>API调用</td><td>管理端智能助手</td><td>54,820</td><td>38.2万</td><td>¥1,720</td><td>280</td><td>0.08%</td><td>0.05%</td><td><span class="tag tag-green">启用</span></td><td class="td-actions"><a class="link">编辑</a> <a class="link">调试日志</a></td></tr>
|
||||
<tr><td>LLM-003</td><td>文心一言</td><td>sk-****f5c9</td><td>https://aip.baidubce.com/rpc</td><td>百度</td><td>ERNIE-4.0</td><td>API调用</td><td>小程序AI营养顾问</td><td>0</td><td>0</td><td>¥0</td><td>—</td><td>—</td><td>—</td><td><span class="tag tag-orange">停用</span></td><td class="td-actions"><a class="link">编辑</a> <a class="link">调试日志</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -224,6 +235,32 @@ const DynModal={
|
||||
}
|
||||
};
|
||||
|
||||
/* ===== 接入新模型弹窗 ===== */
|
||||
function openAddModel(){
|
||||
const html=`
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>模型名称<span class="req">*</span></label><input type="text" placeholder="请输入模型名称,如 豆包"></div>
|
||||
<div class="add-form-item"><label>供应商<span class="req">*</span></label><select><option value="">请选择</option><option>字节跳动</option><option>深度求索</option><option>百度</option><option>阿里云</option><option>OpenAI</option><option>其他</option></select></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>API_KEY<span class="req">*</span></label><input type="text" placeholder="请输入API_KEY"></div>
|
||||
<div class="add-form-item"><label>API_URL<span class="req">*</span></label><input type="text" placeholder="如 https://api.example.com/v1"></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>版本<span class="req">*</span></label><input type="text" placeholder="如 Doubao-pro-32k"></div>
|
||||
<div class="add-form-item"><label>接入方式<span class="req">*</span></label><select><option value="">请选择</option><option>API调用</option><option>SDK接入</option><option>私有化部署</option></select></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item" style="grid-column:1/-1"><label>使用场景<span class="req">*</span></label><textarea placeholder="请输入使用场景,如 小程序AI营养顾问、管理端智能助手"></textarea></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>初始状态<span class="req">*</span></label><select><option>启用</option><option>停用</option></select></div>
|
||||
<div class="add-form-item"><label>模型编号</label><input type="text" value="LLM-004" readonly style="background:#F5F5F5;color:#999;"></div>
|
||||
</div>`;
|
||||
const footer='<button class="btn btn-default" onclick="DynModal.close()">取消</button><button class="btn btn-primary" onclick="DynModal.close()">确定接入</button>';
|
||||
DynModal.open('接入新模型',html,footer,'model-modal');
|
||||
}
|
||||
|
||||
/* ===== 调试日志数据(模拟) ===== */
|
||||
const debugLogData={
|
||||
'LLM-001':[
|
||||
@@ -253,8 +290,8 @@ function showDebugLog(row){
|
||||
const cells=row.querySelectorAll('td');
|
||||
const modelCode=cells[0].textContent.trim();
|
||||
const modelName=cells[1].textContent.trim();
|
||||
const provider=cells[2].textContent.trim();
|
||||
const version=cells[3].textContent.trim();
|
||||
const provider=cells[4].textContent.trim();
|
||||
const version=cells[5].textContent.trim();
|
||||
const records=debugLogData[modelCode]||[];
|
||||
|
||||
const statusTag=s=>s==='成功'?'tag-green':s==='超时'?'tag-orange':'tag-red';
|
||||
@@ -279,7 +316,7 @@ function showDebugLog(row){
|
||||
<div class="log-dev-info">
|
||||
<span>模型编号:<strong>${modelCode}</strong></span>
|
||||
<span>模型名称:<strong>${modelName}</strong></span>
|
||||
<span>提供商:<strong>${provider}</strong></span>
|
||||
<span>供应商:<strong>${provider}</strong></span>
|
||||
<span>版本:<strong>${version}</strong></span>
|
||||
</div>
|
||||
${tableHtml}`;
|
||||
@@ -287,12 +324,56 @@ function showDebugLog(row){
|
||||
DynModal.open('调试日志 — '+modelName,html,'<button class="btn btn-default" onclick="DynModal.close()">关闭</button>','log-modal');
|
||||
}
|
||||
|
||||
/* ===== 编辑模型弹窗 ===== */
|
||||
function openEditModel(row){
|
||||
const cells=row.querySelectorAll('td');
|
||||
const modelCode=cells[0].textContent.trim();
|
||||
const modelName=cells[1].textContent.trim();
|
||||
const apiKey=cells[2].textContent.trim();
|
||||
const apiUrl=cells[3].textContent.trim();
|
||||
const provider=cells[4].textContent.trim();
|
||||
const version=cells[5].textContent.trim();
|
||||
const accessWay=cells[6].textContent.trim();
|
||||
const scene=cells[7].textContent.trim();
|
||||
const statusText=cells[14].textContent.trim();
|
||||
|
||||
const providers=['字节跳动','深度求索','百度','阿里云','OpenAI','其他'];
|
||||
const accessWays=['API调用','SDK接入','私有化部署'];
|
||||
const selOpt=(opts,cur)=>opts.map(o=>`<option${o===cur?' selected':''}>${o}</option>`).join('');
|
||||
|
||||
const html=`
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>模型名称<span class="req">*</span></label><input type="text" value="${modelName}"></div>
|
||||
<div class="add-form-item"><label>供应商<span class="req">*</span></label><select>${selOpt(providers,provider)}</select></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>API_KEY<span class="req">*</span></label><input type="text" value="${apiKey}"></div>
|
||||
<div class="add-form-item"><label>API_URL<span class="req">*</span></label><input type="text" value="${apiUrl}"></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>版本<span class="req">*</span></label><input type="text" value="${version}"></div>
|
||||
<div class="add-form-item"><label>接入方式<span class="req">*</span></label><select>${selOpt(accessWays,accessWay)}</select></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item" style="grid-column:1/-1"><label>使用场景<span class="req">*</span></label><textarea>${scene}</textarea></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>状态<span class="req">*</span></label><select>${selOpt(['启用','停用'],statusText)}</select></div>
|
||||
<div class="add-form-item"><label>模型编号</label><input type="text" value="${modelCode}" readonly style="background:#F5F5F5;color:#999;"></div>
|
||||
</div>`;
|
||||
const footer='<button class="btn btn-default" onclick="DynModal.close()">取消</button><button class="btn btn-primary" onclick="DynModal.close()">保存</button>';
|
||||
DynModal.open('编辑模型 — '+modelName,html,footer,'model-modal');
|
||||
}
|
||||
|
||||
/* ===== 事件绑定 ===== */
|
||||
document.querySelectorAll('tbody tr').forEach(row=>{
|
||||
row.querySelectorAll('.td-actions .link').forEach(link=>{
|
||||
if(link.textContent.includes('调试日志')){
|
||||
link.addEventListener('click',()=>showDebugLog(row));
|
||||
}
|
||||
if(link.textContent.includes('编辑')){
|
||||
link.addEventListener('click',()=>openEditModel(row));
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -119,6 +119,15 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
.test-result__title{font-size:var(--font-sm);color:var(--success);font-weight:600;margin-bottom:8px;}
|
||||
.test-result__content{font-size:var(--font-base);color:var(--text-primary);line-height:1.6;}
|
||||
.test-result__score{font-size:var(--font-lg);font-weight:700;color:var(--success);}
|
||||
/* 新增模型表单 */
|
||||
.add-form-row{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px;}
|
||||
.add-form-item{display:flex;flex-direction:column;gap:6px;}
|
||||
.add-form-item label{font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;}
|
||||
.add-form-item label .req{color:var(--danger);margin-left:2px;}
|
||||
.add-form-item input,.add-form-item select{height:36px;border:1px solid var(--border);border-radius:var(--radius-sm);padding:0 12px;font-size:var(--font-sm);outline:none;background:#fff;width:100%;}
|
||||
.add-form-item input:focus,.add-form-item select:focus{border-color:var(--primary);}
|
||||
.add-form-item select{padding-right:28px;appearance: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;cursor:pointer;}
|
||||
.dyn-modal.model-modal{width:640px;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -197,7 +206,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
|
||||
<!-- 操作栏 -->
|
||||
<div class="action-bar">
|
||||
<button class="btn btn-primary">➕ 新增模型</button>
|
||||
<button class="btn btn-primary" onclick="openAddModel()">➕ 新增模型</button>
|
||||
<button class="btn btn-default">📊 评估报告</button>
|
||||
</div>
|
||||
|
||||
@@ -358,6 +367,33 @@ function showOnlineTest(row){
|
||||
DynModal.open('在线测试 — '+modelName,html,'<button class="btn btn-default" onclick="DynModal.close()">关闭</button>','test-modal');
|
||||
}
|
||||
|
||||
/* ===== 新增模型弹窗 ===== */
|
||||
function openAddModel(){
|
||||
const html=`
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>模型名称<span class="req">*</span></label><input type="text" placeholder="请输入模型名称"></div>
|
||||
<div class="add-form-item"><label>模型类型<span class="req">*</span></label><select><option value="">请选择</option><option>营养计算</option><option>疾病预测</option><option>智能配餐</option><option>消费预测</option><option>食材损耗预测</option><option>过敏原识别</option></select></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>版本号<span class="req">*</span></label><input type="text" placeholder="如 v1.0.0"></div>
|
||||
<div class="add-form-item"><label>版本文件<span class="req">*</span></label><input type="file" style="padding:6px 12px;"></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>准确率</label><input type="text" placeholder="如 92.5%"></div>
|
||||
<div class="add-form-item"><label>推理延迟(ms)</label><input type="number" placeholder="如 45" min="0"></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>模型大小(MB)</label><input type="number" placeholder="如 128" min="0"></div>
|
||||
<div class="add-form-item"><label>关联业务模块<span class="req">*</span></label><input type="text" placeholder="如 营养点餐/营养管理"></div>
|
||||
</div>
|
||||
<div class="add-form-row">
|
||||
<div class="add-form-item"><label>初始状态<span class="req">*</span></label><select><option>在线</option><option>离线</option></select></div>
|
||||
<div class="add-form-item"><label>模型编号</label><input type="text" value="SM-007" readonly style="background:#F5F5F5;color:#999;"></div>
|
||||
</div>`;
|
||||
const footer='<button class="btn btn-default" onclick="DynModal.close()">取消</button><button class="btn btn-primary" onclick="DynModal.close()">确定新增</button>';
|
||||
DynModal.open('新增模型',html,footer,'model-modal');
|
||||
}
|
||||
|
||||
/* ===== 事件绑定 ===== */
|
||||
document.querySelectorAll('tbody tr').forEach(row=>{
|
||||
row.querySelectorAll('.td-actions .link').forEach(link=>{
|
||||
|
||||
@@ -303,12 +303,12 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
<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>实时重量(kg)</th><th>累计取餐重量</th><th>累计上餐生重(kg)</th><th>累计上餐重量</th><th>最高温度</th><th>最低温度</th><th>保鲜时间</th><th>取餐人次</th><th>取餐视频</th><th>上餐视频</th><th>操作</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区早餐线</td><td>早餐</td><td>00022号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>06:50</td><td>07:28</td><td>小米粥</td><td>¥5</td><td>¥1,600</td><td>12.6</td><td><a class="link">9.8kg</a></td><td>14.2</td><td><a class="link">12.6kg</a></td><td>68℃</td><td>55℃</td><td>09:30</td><td>320人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>B区早餐线</td><td>早餐</td><td>00023号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>06:55</td><td>07:35</td><td>燕麦粥</td><td>¥4</td><td>¥1,144</td><td>8.4</td><td><a class="link">6.2kg</a></td><td>9.6</td><td><a class="link">8.4kg</a></td><td>65℃</td><td>55℃</td><td>09:30</td><td>286人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>00025号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>10:30</td><td>11:30</td><td>宫保鸡丁</td><td>¥14</td><td>¥6,804</td><td>38.2</td><td><a class="link">31.6kg</a></td><td>44.0</td><td><a class="link">38.2kg</a></td><td>75℃</td><td>71℃</td><td>13:30</td><td>486人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>00026号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>10:35</td><td>11:38</td><td>红烧肉</td><td>¥16</td><td>¥6,592</td><td>42.6</td><td><a class="link">38.4kg</a></td><td>48.5</td><td><a class="link">42.6kg</a></td><td>72℃</td><td>68℃</td><td>13:30</td><td>412人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>C区快餐线</td><td>中餐</td><td>00027号秤</td><td><span class="tag tag-orange">无网络</span></td><td><span class="tag tag-gray">单称</span></td><td><span class="tag tag-blue">加餐</span></td><td>10:40</td><td>12:12</td><td>番茄炒蛋</td><td>¥8</td><td>¥1,024</td><td>16.8</td><td><a class="link">14.2kg</a></td><td>18.6</td><td><a class="link">16.8kg</a></td><td>74℃</td><td>70℃</td><td>13:30</td><td>128人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>三号食堂</td><td>D区晚餐线</td><td>晚餐</td><td>00028号秤</td><td><span class="tag tag-gray">未开机</span></td><td><span class="tag tag-gray">双称</span></td><td><span class="tag tag-gray">待上餐</span></td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>19:30</td><td>—</td><td>—</td><td>—</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区早餐线</td><td>早餐</td><td>00022号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>06:50</td><td>07:28</td><td>小米粥</td><td>¥5</td><td>¥1,600</td><td>12.6</td><td><a class="link">9.8kg</a></td><td>14.2</td><td><a class="link">12.6kg</a></td><td>68℃</td><td>55℃</td><td>09:30</td><td>320人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>B区早餐线</td><td>早餐</td><td>00023号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>06:55</td><td>07:35</td><td>燕麦粥</td><td>¥4</td><td>¥1,144</td><td>8.4</td><td><a class="link">6.2kg</a></td><td>9.6</td><td><a class="link">8.4kg</a></td><td>65℃</td><td>55℃</td><td>09:30</td><td>286人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>00025号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>10:30</td><td>11:30</td><td>宫保鸡丁</td><td>¥14</td><td>¥6,804</td><td>38.2</td><td><a class="link">31.6kg</a></td><td>44.0</td><td><a class="link">38.2kg</a></td><td>75℃</td><td>71℃</td><td>13:30</td><td>486人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>00026号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>10:35</td><td>11:38</td><td>红烧肉</td><td>¥16</td><td>¥6,592</td><td>42.6</td><td><a class="link">38.4kg</a></td><td>48.5</td><td><a class="link">42.6kg</a></td><td>72℃</td><td>68℃</td><td>13:30</td><td>412人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>C区快餐线</td><td>中餐</td><td>00027号秤</td><td><span class="tag tag-orange">无网络</span></td><td><span class="tag tag-gray">单称</span></td><td><span class="tag tag-blue">加餐</span></td><td>10:40</td><td>12:12</td><td>番茄炒蛋</td><td>¥8</td><td>¥1,024</td><td>16.8</td><td><a class="link">14.2kg</a></td><td>18.6</td><td><a class="link">16.8kg</a></td><td>74℃</td><td>70℃</td><td>13:30</td><td>128人</td><td><a class="link">▶ 取餐</a></td><td><a class="link">▶ 上餐</a></td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>三号食堂</td><td>D区晚餐线</td><td>晚餐</td><td>00028号秤</td><td><span class="tag tag-gray">未开机</span></td><td><span class="tag tag-gray">双称</span></td><td><span class="tag tag-gray">待上餐</span></td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>19:30</td><td>—</td><td>—</td><td>—</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -347,13 +347,13 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="summary-row"><td>汇总</td><td>—</td><td>—</td><td>—</td><td>84道</td><td>1,286</td><td>1,540</td><td>¥58,420</td><td>5,612人</td><td>229g</td><td>—</td><td>—</td><td>3次</td><td>—</td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>12道</td><td>256</td><td>312</td><td>¥14,280</td><td>1,140人</td><td>225g</td><td>78℃</td><td>68℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>10道</td><td>218</td><td>268</td><td>¥12,640</td><td>980人</td><td>222g</td><td>76℃</td><td>66℃</td><td>1次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区早餐线</td><td>早餐</td><td>8道</td><td>148</td><td>182</td><td>¥7,400</td><td>980人</td><td>151g</td><td>70℃</td><td>55℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-18</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>12道</td><td>248</td><td>304</td><td>¥13,860</td><td>1,100人</td><td>226g</td><td>77℃</td><td>67℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-18</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>10道</td><td>210</td><td>258</td><td>¥12,180</td><td>960人</td><td>219g</td><td>75℃</td><td>65℃</td><td>1次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-18</td><td>二号食堂</td><td>B区早餐线</td><td>早餐</td><td>8道</td><td>142</td><td>176</td><td>¥7,100</td><td>920人</td><td>154g</td><td>69℃</td><td>54℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-17</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>11道</td><td>212</td><td>260</td><td>¥11,860</td><td>960人</td><td>221g</td><td>76℃</td><td>66℃</td><td>1次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>12道</td><td>256</td><td>312</td><td>¥14,280</td><td>1,140人</td><td>225g</td><td>78℃</td><td>68℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>10道</td><td>218</td><td>268</td><td>¥12,640</td><td>980人</td><td>222g</td><td>76℃</td><td>66℃</td><td>1次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区早餐线</td><td>早餐</td><td>8道</td><td>148</td><td>182</td><td>¥7,400</td><td>980人</td><td>151g</td><td>70℃</td><td>55℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-18</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>12道</td><td>248</td><td>304</td><td>¥13,860</td><td>1,100人</td><td>226g</td><td>77℃</td><td>67℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-18</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>10道</td><td>210</td><td>258</td><td>¥12,180</td><td>960人</td><td>219g</td><td>75℃</td><td>65℃</td><td>1次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-18</td><td>二号食堂</td><td>B区早餐线</td><td>早餐</td><td>8道</td><td>142</td><td>176</td><td>¥7,100</td><td>920人</td><td>154g</td><td>69℃</td><td>54℃</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-17</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>11道</td><td>212</td><td>260</td><td>¥11,860</td><td>960人</td><td>221g</td><td>76℃</td><td>66℃</td><td>1次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -389,12 +389,12 @@ tbody tr:hover td:last-child{background:#F8FBFF;}
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr class="summary-row"><td>汇总</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>84道</td><td>¥58,420</td><td>1,286</td><td>1,720</td><td>1,540</td><td>—</td><td>—</td><td>5,612人</td><td>229g</td><td>3次</td><td>—</td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区早餐线</td><td>早餐</td><td>00022号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>8道</td><td>¥7,400</td><td>148</td><td>186</td><td>182</td><td>70℃</td><td>55℃</td><td>980人</td><td>151g</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>B区早餐线</td><td>早餐</td><td>00023号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>6道</td><td>¥4,860</td><td>92</td><td>118</td><td>108</td><td>68℃</td><td>54℃</td><td>720人</td><td>128g</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>00025号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>12道</td><td>¥14,280</td><td>256</td><td>342</td><td>312</td><td>78℃</td><td>68℃</td><td>1,140人</td><td>225g</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>00026号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>10道</td><td>¥12,640</td><td>218</td><td>294</td><td>268</td><td>76℃</td><td>66℃</td><td>980人</td><td>222g</td><td>1次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>C区快餐线</td><td>中餐</td><td>00027号秤</td><td><span class="tag tag-orange">无网络</span></td><td><span class="tag tag-gray">单称</span></td><td><span class="tag tag-blue">加餐</span></td><td>6道</td><td>¥4,820</td><td>92</td><td>128</td><td>120</td><td>74℃</td><td>70℃</td><td>516人</td><td>178g</td><td>2次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>三号食堂</td><td>D区晚餐线</td><td>晚餐</td><td>00028号秤</td><td><span class="tag tag-gray">未开机</span></td><td><span class="tag tag-gray">双称</span></td><td><span class="tag tag-gray">待上餐</span></td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>0次</td><td class="td-actions"><a class="link">详情</a> <a class="link">编辑</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区早餐线</td><td>早餐</td><td>00022号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>8道</td><td>¥7,400</td><td>148</td><td>186</td><td>182</td><td>70℃</td><td>55℃</td><td>980人</td><td>151g</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>B区早餐线</td><td>早餐</td><td>00023号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>6道</td><td>¥4,860</td><td>92</td><td>118</td><td>108</td><td>68℃</td><td>54℃</td><td>720人</td><td>128g</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>A区中餐线</td><td>中餐</td><td>00025号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">单称</span></td><td><span class="tag tag-green">开餐</span></td><td>12道</td><td>¥14,280</td><td>256</td><td>342</td><td>312</td><td>78℃</td><td>68℃</td><td>1,140人</td><td>225g</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>一号食堂</td><td>B区中餐线</td><td>中餐</td><td>00026号秤</td><td><span class="tag tag-green">正常</span></td><td><span class="tag tag-blue">双称</span></td><td><span class="tag tag-green">开餐</span></td><td>10道</td><td>¥12,640</td><td>218</td><td>294</td><td>268</td><td>76℃</td><td>66℃</td><td>980人</td><td>222g</td><td>1次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>二号食堂</td><td>C区快餐线</td><td>中餐</td><td>00027号秤</td><td><span class="tag tag-orange">无网络</span></td><td><span class="tag tag-gray">单称</span></td><td><span class="tag tag-blue">加餐</span></td><td>6道</td><td>¥4,820</td><td>92</td><td>128</td><td>120</td><td>74℃</td><td>70℃</td><td>516人</td><td>178g</td><td>2次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
<tr><td>2026-05-19</td><td>三号食堂</td><td>D区晚餐线</td><td>晚餐</td><td>00028号秤</td><td><span class="tag tag-gray">未开机</span></td><td><span class="tag tag-gray">双称</span></td><td><span class="tag tag-gray">待上餐</span></td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>—</td><td>0次</td><td class="td-actions"><a class="link">详情</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
@@ -129,6 +129,15 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
.fault-table tbody tr:last-child td{border-bottom:none;}
|
||||
.fault-table tbody tr:hover{background:#F8FBFF;}
|
||||
.fault-empty{text-align:center;padding:40px 0;color:var(--text-placeholder);font-size:var(--font-sm);}
|
||||
/* 页面信息栏 */
|
||||
.page-header-bar{display:flex;align-items:center;justify-content:space-between;background:#fff;border-radius:var(--radius-md);padding:16px 24px;margin-bottom:16px;box-shadow:var(--shadow-sm);}
|
||||
.page-header-bar__left{display:flex;align-items:center;gap:12px;}
|
||||
.page-header-bar__title{font-size:var(--font-lg);font-weight:700;color:var(--text-primary);}
|
||||
.page-header-bar__meta{font-size:var(--font-sm);color:var(--text-placeholder);}
|
||||
.page-header-bar__right{display:flex;align-items:center;gap:12px;}
|
||||
.page-header-bar__right label{font-size:var(--font-sm);color:var(--text-secondary);white-space:nowrap;}
|
||||
.page-header-bar__right .canteen-select{height:36px;border:2px solid var(--primary);border-radius:var(--radius-sm);padding:0 32px 0 14px;font-size:var(--font-sm);color:var(--primary);font-weight:500;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='%231890FF'/%3E%3C/svg%3E") no-repeat right 12px center;appearance:none;cursor:pointer;min-width:140px;}
|
||||
|
||||
/* 确认弹窗 */
|
||||
.confirm-modal{width:420px;}
|
||||
.confirm-icon{display:flex;align-items:center;justify-content:center;margin-bottom:16px;}
|
||||
@@ -202,6 +211,24 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
|
||||
<!-- 主内容区 -->
|
||||
<div class="main">
|
||||
|
||||
<!-- 页面信息栏 -->
|
||||
<div class="page-header-bar">
|
||||
<div class="page-header-bar__left">
|
||||
<span class="page-header-bar__title">终端管理</span>
|
||||
<span class="page-header-bar__meta">2026-05-20 · 数据实时更新</span>
|
||||
</div>
|
||||
<div class="page-header-bar__right">
|
||||
<label>当前食堂</label>
|
||||
<select class="canteen-select" id="globalCanteen">
|
||||
<option value="1">一食堂(东区)</option>
|
||||
<option value="2">二食堂(西区)</option>
|
||||
<option value="3">三食堂(北区)</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- 统计卡片 -->
|
||||
<div class="stats-row">
|
||||
<div class="stat-card"><div class="stat-card__icon blue">🖥️</div><div class="stat-card__info"><div class="stat-card__value">32</div><div class="stat-card__label">设备总数</div></div></div>
|
||||
@@ -212,11 +239,9 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
|
||||
<!-- 筛选栏 -->
|
||||
<div class="filter-bar">
|
||||
<div class="filter-item"><label>设备名称/编号</label><input class="filter-input" type="text" placeholder="请输入"></div>
|
||||
<div class="filter-item"><label>设备类型</label><select class="filter-select"><option>全部</option><option>智能取餐柜</option><option>点餐屏</option><option>餐线秤台</option><option>体脂秤</option></select></div>
|
||||
<div class="filter-item"><label>所在区域</label><select class="filter-select"><option>全部</option><option>A区</option><option>B区</option><option>C区</option><option>D区</option></select></div>
|
||||
<div class="filter-item"><label>厂家品牌</label><select class="filter-select"><option>全部</option><option>海康威视</option><option>海尔智家</option><option>大华技术</option><option>华为智选</option></select></div>
|
||||
<div class="filter-item"><label>责任人</label><select class="filter-select"><option>全部</option><option>张运维</option><option>李运维</option><option>王运维</option></select></div>
|
||||
<div class="filter-item"><label>设备名称</label><input class="filter-input" type="text" placeholder="请输入设备名称"></div>
|
||||
<div class="filter-item"><label>设备编号</label><input class="filter-input" type="text" placeholder="请输入设备编号"></div>
|
||||
<div class="filter-item"><label>设备类型</label><select class="filter-select"><option>全部</option><option>智能取餐柜</option><option>点餐屏</option><option>餐线秤台</option></select></div>
|
||||
<div class="filter-item"><label>状态</label><select class="filter-select"><option>全部</option><option>在线</option><option>离线</option><option>故障</option></select></div>
|
||||
<button class="btn btn-primary">查询</button>
|
||||
<button class="btn btn-default">重置</button>
|
||||
@@ -235,14 +260,14 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="table-card__content">
|
||||
<table>
|
||||
<thead><tr><th>设备编号</th><th>SN序列号</th><th>设备名称</th><th>设备类型</th><th>厂家品牌</th><th>所在区域</th><th>地理位置</th><th>责任人</th><th>网络类型</th><th>IP地址/设备ID</th><th>固件版本</th><th>安装日期</th><th>在线状态</th><th>设备健康评分</th><th>今日使用次数</th><th>最近心跳时间</th><th>运行天数</th><th>累计时长(分钟)</th><th>最近维护时间</th><th>故障记录数</th><th>操作</th></tr></thead>
|
||||
<thead><tr><th>设备编号</th><th>设备名称</th><th>设备类型</th><th>厂家品牌</th><th>责任人</th><th>网络类型</th><th>IP地址/设备ID</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>DEV-001</td><td>SN-A001-2024</td><td>1号点餐屏</td><td>点餐屏</td><td>海康威视</td><td>A区</td><td>A区入口-东侧</td><td>张运维</td><td>WiFi</td><td>192.168.1.101</td><td>v3.2.1</td><td>2024-08-15</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">98分</span></td><td>486</td><td>2026-04-22 11:30:22</td><td>615</td><td>362,400</td><td>2026-03-20</td><td>2</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-002</td><td>SN-A002-2024</td><td>智能取餐柜-01</td><td>智能取餐柜</td><td>海尔智家</td><td>A区</td><td>A区取餐区-1号位</td><td>李运维</td><td>有线</td><td>192.168.1.102</td><td>v2.8.0</td><td>2024-08-15</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">100分</span></td><td>312</td><td>2026-04-22 11:30:18</td><td>615</td><td>498,720</td><td>2026-04-01</td><td>0</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-003</td><td>SN-B001-2024</td><td>2号点餐屏</td><td>点餐屏</td><td>海康威视</td><td>B区</td><td>B区入口-西侧</td><td>张运维</td><td>WiFi</td><td>192.168.1.103</td><td>v3.2.1</td><td>2024-10-01</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">92分</span></td><td>398</td><td>2026-04-22 11:30:25</td><td>568</td><td>298,800</td><td>2026-04-10</td><td>1</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-004</td><td>SN-B002-2024</td><td>智能取餐柜-02</td><td>智能取餐柜</td><td>海尔智家</td><td>B区</td><td>B区取餐区-1号位</td><td>李运维</td><td>有线</td><td>192.168.1.104</td><td>v2.7.3</td><td>2024-10-01</td><td><span class="tag tag-red">离线</span></td><td><span class="tag tag-red">0分</span></td><td>0</td><td>2026-04-22 09:18:44</td><td>568</td><td>423,600</td><td>2026-04-15</td><td>3</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-005</td><td>SN-A003-2022</td><td>餐线秤台-00025</td><td>餐线秤台</td><td>大华技术</td><td>A区</td><td>A区餐线-1号位</td><td>王运维</td><td>有线</td><td>DEV-00025</td><td>v1.5.2</td><td>2022-06-10</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">99分</span></td><td>1,280</td><td>2026-04-22 11:30:20</td><td>1,412</td><td>1,016,640</td><td>2026-03-01</td><td>0</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-006</td><td>SN-C001-2023</td><td>体脂秤-01</td><td>体脂秤</td><td>华为智选</td><td>C区</td><td>健身区入口-南侧</td><td>张运维</td><td>WiFi</td><td>192.168.1.106</td><td>v2.1.0</td><td>2023-12-01</td><td><span class="tag tag-orange">故障</span></td><td><span class="tag tag-red">45分</span></td><td>0</td><td>2026-04-22 10:55:08</td><td>873</td><td>78,540</td><td>2026-02-28</td><td>1</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-001</td><td>1号点餐屏</td><td>点餐屏</td><td>海康威视</td><td>张运维</td><td>WiFi</td><td>192.168.1.101</td><td>v3.2.1</td><td>2024-08-15</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">98分</span></td><td>486</td><td>2026-04-22 11:30:22</td><td>615</td><td>362,400</td><td>2026-03-20</td><td>2</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-002</td><td>智能取餐柜-01</td><td>智能取餐柜</td><td>海尔智家</td><td>李运维</td><td>有线</td><td>192.168.1.102</td><td>v2.8.0</td><td>2024-08-15</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">100分</span></td><td>312</td><td>2026-04-22 11:30:18</td><td>615</td><td>498,720</td><td>2026-04-01</td><td>0</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-003</td><td>2号点餐屏</td><td>点餐屏</td><td>海康威视</td><td>张运维</td><td>WiFi</td><td>192.168.1.103</td><td>v3.2.1</td><td>2024-10-01</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">92分</span></td><td>398</td><td>2026-04-22 11:30:25</td><td>568</td><td>298,800</td><td>2026-04-10</td><td>1</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-004</td><td>智能取餐柜-02</td><td>智能取餐柜</td><td>海尔智家</td><td>李运维</td><td>有线</td><td>192.168.1.104</td><td>v2.7.3</td><td>2024-10-01</td><td><span class="tag tag-red">离线</span></td><td><span class="tag tag-red">0分</span></td><td>0</td><td>2026-04-22 09:18:44</td><td>568</td><td>423,600</td><td>2026-04-15</td><td>3</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-005</td><td>餐线秤台-00025</td><td>餐线秤台</td><td>大华技术</td><td>王运维</td><td>有线</td><td>DEV-00025</td><td>v1.5.2</td><td>2022-06-10</td><td><span class="tag tag-green">在线</span></td><td><span class="tag tag-green">99分</span></td><td>1,280</td><td>2026-04-22 11:30:20</td><td>1,412</td><td>1,016,640</td><td>2026-03-01</td><td>0</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
<tr><td>DEV-006</td><td>体脂秤-01</td><td>体脂秤</td><td>华为智选</td><td>张运维</td><td>WiFi</td><td>192.168.1.106</td><td>v2.1.0</td><td>2023-12-01</td><td><span class="tag tag-orange">故障</span></td><td><span class="tag tag-red">45分</span></td><td>0</td><td>2026-04-22 10:55:08</td><td>873</td><td>78,540</td><td>2026-02-28</td><td>1</td><td class="td-actions"><a class="link">故障记录</a> <a class="link">远程重启</a></td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -259,15 +284,14 @@ tbody tr:hover{background:#F8FBFF;}
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="form-grid">
|
||||
<div class="form-item"><label>设备编号<span class="required">*</span></label><input type="text" placeholder="请输入设备编号"></div>
|
||||
<div class="form-item"><label>设备名称<span class="required">*</span></label><input type="text" placeholder="请输入设备名称"></div>
|
||||
<div class="form-item"><label>SN序列号<span class="required">*</span></label><input type="text" placeholder="请输入SN序列号"></div>
|
||||
<div class="form-item"><label>设备类型<span class="required">*</span></label><select><option>请选择</option><option>智能取餐柜</option><option>点餐屏</option><option>配比秤</option><option>餐线秤台</option><option>摄像头</option><option>智能电表</option><option>智能水表</option><option>智能气表</option><option>体脂秤</option></select></div>
|
||||
<div class="form-item"><label>厂家品牌<span class="required">*</span></label><input type="text" placeholder="请输入厂家品牌"></div>
|
||||
<div class="form-item"><label>所在区域<span class="required">*</span></label><select><option>请选择</option><option>A区</option><option>B区</option><option>C区</option><option>D区</option></select></div>
|
||||
<div class="form-item"><label>地理位置<span class="required">*</span></label><input type="text" placeholder="请输入地理位置"></div>
|
||||
<div class="form-item"><label>责任人<span class="required">*</span></label><input type="text" placeholder="请输入责任人"></div>
|
||||
<div class="form-item"><label>网络类型</label><select><option>请选择</option><option>有线</option><option>WiFi</option><option>4G</option><option>蓝牙</option></select></div>
|
||||
<div class="form-item"><label>IP地址/设备ID</label><input type="text" placeholder="请输入IP地址或设备ID"></div>
|
||||
<div class="form-item"><label>厂家</label><input type="text" placeholder="请输入厂家"></div>
|
||||
<div class="form-item"><label>型号</label><input type="text" placeholder="请输入型号"></div>
|
||||
<div class="form-item"><label>责任人</label><input type="text" placeholder="请输入责任人"></div>
|
||||
<div class="form-item"><label>网络类型</label><select><option>请选择</option><option>WiFi</option><option>有线</option><option>蓝牙</option></select></div>
|
||||
<div class="form-item"><label>IP地址</label><input type="text" placeholder="请输入IP地址"></div>
|
||||
<div class="form-item"><label>固件版本</label><input type="text" placeholder="请输入固件版本"></div>
|
||||
<div class="form-item"><label>安装日期</label><input type="date"></div>
|
||||
</div>
|
||||
@@ -311,21 +335,21 @@ const DynModal={
|
||||
/* ===== 故障记录数据(模拟) ===== */
|
||||
const faultData={
|
||||
'DEV-001':[
|
||||
{time:'2026-03-18 14:22',type:'触屏无响应',level:'中',status:'已修复',handler:'张运维'},
|
||||
{time:'2025-12-05 09:10',type:'网络断连',level:'低',status:'已修复',handler:'李运维'}
|
||||
{time:'2026-03-18 14:22',type:'触屏无响应',level:'中',status:'已修复',handler:'张运维',repairTime:'2026-03-18 16:00',remark:'更换触屏模块'},
|
||||
{time:'2025-12-05 09:10',type:'网络断连',level:'低',status:'已修复',handler:'李运维',repairTime:'2025-12-05 10:30',remark:'重启路由器恢复'}
|
||||
],
|
||||
'DEV-002':[],
|
||||
'DEV-003':[
|
||||
{time:'2026-04-08 16:35',type:'显示花屏',level:'高',status:'已修复',handler:'张运维'}
|
||||
{time:'2026-04-08 16:35',type:'显示花屏',level:'高',status:'已修复',handler:'张运维',repairTime:'2026-04-09 10:00',remark:'更换显示屏'}
|
||||
],
|
||||
'DEV-004':[
|
||||
{time:'2026-04-22 09:18',type:'主板故障',level:'高',status:'维修中',handler:'李运维'},
|
||||
{time:'2026-02-14 11:00',type:'电源异常',level:'中',status:'已修复',handler:'王运维'},
|
||||
{time:'2025-11-20 08:45',type:'网络断连',level:'低',status:'已修复',handler:'李运维'}
|
||||
{time:'2026-04-22 09:18',type:'主板故障',level:'高',status:'待修复',handler:'李运维',repairTime:'',remark:'等待配件到货'},
|
||||
{time:'2026-02-14 11:00',type:'电源异常',level:'中',status:'已修复',handler:'王运维',repairTime:'2026-02-14 15:00',remark:'更换电源适配器'},
|
||||
{time:'2025-11-20 08:45',type:'网络断连',level:'低',status:'已修复',handler:'李运维',repairTime:'2025-11-20 09:30',remark:'网线接触不良重新插拔'}
|
||||
],
|
||||
'DEV-005':[],
|
||||
'DEV-006':[
|
||||
{time:'2026-04-20 10:30',type:'传感器异常',level:'高',status:'维修中',handler:'张运维'}
|
||||
{time:'2026-04-20 10:30',type:'传感器异常',level:'高',status:'待修复',handler:'张运维',repairTime:'',remark:'传感器校准失败,需返厂'}
|
||||
]
|
||||
};
|
||||
|
||||
@@ -333,8 +357,8 @@ const faultData={
|
||||
function showFaultLog(row){
|
||||
const cells=row.querySelectorAll('td');
|
||||
const devCode=cells[0].textContent.trim();
|
||||
const devName=cells[2].textContent.trim();
|
||||
const devType=cells[3].textContent.trim();
|
||||
const devName=cells[1].textContent.trim();
|
||||
const devType=cells[2].textContent.trim();
|
||||
const records=faultData[devCode]||[];
|
||||
|
||||
let tableHtml='';
|
||||
@@ -342,16 +366,19 @@ function showFaultLog(row){
|
||||
tableHtml='<div class="fault-empty">暂无故障记录</div>';
|
||||
}else{
|
||||
const levelTag=l=>l==='高'?'tag-red':l==='中'?'tag-orange':'tag-green';
|
||||
const statusTag=s=>s==='维修中'?'tag-orange':s==='已修复'?'tag-green':'tag-gray';
|
||||
const statusTag=s=>s==='待修复'?'tag-orange':'tag-green';
|
||||
const rows=records.map(r=>`<tr>
|
||||
<td>${r.time}</td>
|
||||
<td>${r.type}</td>
|
||||
<td><span class="tag ${levelTag(r.level)}">${r.level}</span></td>
|
||||
<td><span class="tag ${statusTag(r.status)}">${r.status}</span></td>
|
||||
<td>${r.handler}</td>
|
||||
<td>${r.repairTime||'—'}</td>
|
||||
<td>${r.remark||'—'}</td>
|
||||
<td><a class="link">编辑</a> <a class="link" style="color:var(--danger)">删除</a></td>
|
||||
</tr>`).join('');
|
||||
tableHtml=`<table class="fault-table">
|
||||
<thead><tr><th>时间</th><th>故障类型</th><th>等级</th><th>状态</th><th>处理人</th></tr></thead>
|
||||
<thead><tr><th>故障时间</th><th>故障类型</th><th>故障等级</th><th>状态</th><th>维护人</th><th>维护时间</th><th>维护说明</th><th>操作</th></tr></thead>
|
||||
<tbody>${rows}</tbody>
|
||||
</table>`;
|
||||
}
|
||||
@@ -363,9 +390,49 @@ function showFaultLog(row){
|
||||
<span>设备类型:<strong>${devType}</strong></span>
|
||||
<span>故障记录数:<strong>${records.length}</strong></span>
|
||||
</div>
|
||||
<div style="margin:12px 0 8px;text-align:right"><button class="btn btn-primary btn-sm" onclick="showAddFault('${devCode}')">新增</button></div>
|
||||
${tableHtml}`;
|
||||
|
||||
DynModal.open('故障记录 — '+devName,html,'<button class="btn btn-default" onclick="DynModal.close()">关闭</button>','fault-modal');
|
||||
DynModal.open('故障记录 — '+devName,html,'','fault-modal');
|
||||
}
|
||||
|
||||
/* ===== 新增故障记录弹窗(覆盖在原弹窗上) ===== */
|
||||
function showAddFault(devCode){
|
||||
const overlay=document.createElement('div');
|
||||
overlay.className='modal-overlay fault-add-overlay';
|
||||
overlay.style.zIndex='10001';
|
||||
overlay.innerHTML=`
|
||||
<div class="modal fault-modal" style="width:600px">
|
||||
<div class="modal-header"><span class="modal-title">新增故障记录(${devCode})</span><span class="modal-close" onclick="closeFaultAdd()">×</span></div>
|
||||
<div class="modal-body">
|
||||
<div class="form-grid">
|
||||
<div class="form-item"><label>故障时间<span class="required">*</span></label><input type="datetime-local"></div>
|
||||
<div class="form-item"><label>故障类型<span class="required">*</span></label><input type="text" placeholder="请输入故障类型"></div>
|
||||
<div class="form-item"><label>故障等级<span class="required">*</span></label><select><option>请选择</option><option>高</option><option>中</option><option>低</option></select></div>
|
||||
<div class="form-item"><label>状态<span class="required">*</span></label><select id="faultStatusSel" onchange="toggleRepairFields()"><option value="">请选择</option><option value="待修复">待修复</option><option value="已修复">已修复</option></select></div>
|
||||
<div class="form-item" id="repairHandler"><label>维护人</label><input type="text" placeholder="请输入维护人"></div>
|
||||
<div class="form-item" id="repairTime"><label>维护时间</label><input type="datetime-local"></div>
|
||||
<div class="form-item full" id="repairRemark"><label>维护说明</label><textarea placeholder="请输入维护说明"></textarea></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer"><button class="btn btn-default" onclick="closeFaultAdd()">取消</button><button class="btn btn-primary" onclick="closeFaultAdd()">确定</button></div>
|
||||
</div>`;
|
||||
document.body.appendChild(overlay);
|
||||
setTimeout(()=>overlay.classList.add('active'),10);
|
||||
}
|
||||
function closeFaultAdd(){
|
||||
const el=document.querySelector('.fault-add-overlay');
|
||||
if(el){el.classList.remove('active');setTimeout(()=>el.remove(),200);}
|
||||
}
|
||||
function toggleRepairFields(){
|
||||
const val=document.getElementById('faultStatusSel').value;
|
||||
const isRepaired=val==='已修复';
|
||||
const handlerEl=document.querySelector('#repairHandler label');
|
||||
const timeEl=document.querySelector('#repairTime label');
|
||||
const remarkEl=document.querySelector('#repairRemark label');
|
||||
handlerEl.innerHTML=isRepaired?'维护人<span class="required">*</span>':'维护人';
|
||||
timeEl.innerHTML=isRepaired?'维护时间<span class="required">*</span>':'维护时间';
|
||||
remarkEl.innerHTML=isRepaired?'维护说明<span class="required">*</span>':'维护说明';
|
||||
}
|
||||
|
||||
/* ===== 远程重启确认弹窗 ===== */
|
||||
|
||||
@@ -1,5 +1,45 @@
|
||||
# 营养用餐管理端 CHANGELOG
|
||||
|
||||
## [2026-05-22]
|
||||
|
||||
### 增强 — 营养用餐模块多页面交互优化
|
||||
|
||||
- **`din-data-nutri.html`** 营养管理数据
|
||||
- 新增页面信息栏(标题 + 食堂切换下拉,canteen-select 高亮样式)
|
||||
- 新增周选择器(week-picker):覆盖原生日期文字,显示友好的周范围标签
|
||||
- 餐品明细弹窗重构:宽度调整为 900px,移除顶部提示条,底部汇总区移至表格下方,新增 `.dish-tip` 警告样式(橙色背景)
|
||||
- 新增二级弹窗表单样式(wb-form-modal / wb-form-row / wb-form-input 等),支持营养师工作台内嵌表单
|
||||
- 新增 `.modal-overlay.layer` 层叠弹窗样式(z-index:1010)
|
||||
- 新增 `.tag-purple` 标签色
|
||||
|
||||
- **`din-data-benefit.html`** 食材效益
|
||||
- 新增页面信息栏(标题 + 食堂切换下拉)
|
||||
- 食材分类筛选改为二级级联选择器(cascade-picker),支持一级/二级联动选择
|
||||
- 新增「↻ 重置」按钮(btn-reset 样式)
|
||||
- 表格移除「损耗原因」列
|
||||
- 统计周期数据更新为 2026-05
|
||||
|
||||
- **`din-model-llm.html`** 大模型管理
|
||||
- 表格新增「API_KEY」「API_URL」列,「提供商」改为「供应商」
|
||||
- 状态标签由「在用/备用」改为「启用/停用」
|
||||
- 操作列新增「编辑」链接
|
||||
- 新增「接入新模型」弹窗(含模型名称/供应商/API_KEY/API_URL/版本/接入方式/使用场景/初始状态字段)
|
||||
- 新增「编辑模型」弹窗(预填当前行数据,支持修改所有字段)
|
||||
- 调试日志弹窗适配新列索引(provider 从第3列改为第5列)
|
||||
|
||||
- **`din-model-small.html`** 小模型管理
|
||||
- 新增「新增模型」弹窗(含模型名称/类型/版本/部署方式/使用场景/初始状态字段)
|
||||
- 新增弹窗表单通用样式(add-form-row / add-form-item)
|
||||
|
||||
- **`din-terminal.html`** 终端管理
|
||||
- 新增页面信息栏(标题 + 食堂切换下拉)
|
||||
- 筛选栏重构:「设备名称/编号」拆分为两个独立输入框,移除「所在区域」「厂家品牌」「责任人」筛选项
|
||||
- 表格列精简:移除「SN序列号」「所在区域」「地理位置」列
|
||||
- 新增设备弹窗表单字段调整:「SN序列号」改为「设备编号」,新增「型号」字段,移除「所在区域」「地理位置」
|
||||
|
||||
- **`din-order-line.html`** 餐线管理
|
||||
- 三个 Tab(秤台实时/餐线汇总/秤台汇总)操作列统一移除「编辑」链接,仅保留「详情」
|
||||
|
||||
## [2026-05-20]
|
||||
|
||||
### 增强 — 健康生产模块交互重构与食堂切换
|
||||
|
||||
Reference in New Issue
Block a user