@@ -374,6 +397,41 @@ function switchTab(idx){
document.querySelectorAll('.tab-panel').forEach(function(p,i){p.classList.toggle('active',i===idx);});
}
+/* ========== 食堂→餐线联动 ========== */
+function updateLineOptions(){
+ var canteenVal=document.getElementById('filterCanteen').value;
+ var lineSelect=document.getElementById('filterLine');
+ var opts=lineSelect.querySelectorAll('option');
+ opts.forEach(function(opt){
+ if(!opt.value&&!opt.getAttribute('data-canteen')){opt.style.display='';return;}
+ if(!canteenVal){opt.style.display='';return;}
+ opt.style.display=opt.getAttribute('data-canteen')===canteenVal?'':'none';
+ });
+ lineSelect.value='';
+}
+function updateLineOptions2(){
+ var canteenVal=document.getElementById('filterCanteen2').value;
+ var lineSelect=document.getElementById('filterLine2');
+ var opts=lineSelect.querySelectorAll('option');
+ opts.forEach(function(opt){
+ if(!opt.value&&!opt.getAttribute('data-canteen')){opt.style.display='';return;}
+ if(!canteenVal){opt.style.display='';return;}
+ opt.style.display=opt.getAttribute('data-canteen')===canteenVal?'':'none';
+ });
+ lineSelect.value='';
+}
+function updateLineOptions3(){
+ var canteenVal=document.getElementById('filterCanteen3').value;
+ var lineSelect=document.getElementById('filterLine3');
+ var opts=lineSelect.querySelectorAll('option');
+ opts.forEach(function(opt){
+ if(!opt.value&&!opt.getAttribute('data-canteen')){opt.style.display='';return;}
+ if(!canteenVal){opt.style.display='';return;}
+ opt.style.display=opt.getAttribute('data-canteen')===canteenVal?'':'none';
+ });
+ lineSelect.value='';
+}
+
/* ========== 弹窗基础 ========== */
const Modal = {
open(title, bodyHtml) {
@@ -447,7 +505,7 @@ function showPickupDetail(scaleId) {
pageBtns += `
@@ -491,26 +549,236 @@ function showServingDetail(scaleId) {
const rows = servingData[scaleId] || [];
const tbody = rows.map(r => `
| ${r.time} | ${r.batch} | ${r.type} | ${r.dish} | ${r.rawWeight} | ${r.servWeight} | ${r.chef} |
`).join('');
const html = `
- | 时间 | 批次号 | 类型 | 菜品 | 生重 | 上餐重量 | 厨师 |
+ | 时间 | 批次号 | 类型 | 餐品 | 生重 | 上餐重量 | 厨师 |
${tbody}
`;
Modal.open('上餐明细 — ' + scaleId, html);
}
/* ========== 事件绑定 ========== */
+
+/* ========== 右侧抽屉 ========== */
+const Drawer = {
+ open(title, bodyHtml) {
+ this.close();
+ const overlay = document.createElement('div');
+ overlay.className = 'drawer-overlay';
+ overlay.innerHTML = '
' +
+ '' +
+ '
' + bodyHtml + '
' +
+ '
';
+ overlay.addEventListener('click', function(e){ if(e.target===overlay) Drawer.close(); });
+ document.body.appendChild(overlay);
+ },
+ close() {
+ const o = document.querySelector('.drawer-overlay');
+ if(!o) return;
+ o.classList.add('closing');
+ setTimeout(function(){ o.remove(); }, 200);
+ }
+};
+
+function showScaleDetail(row) {
+ var cells = row.querySelectorAll('td');
+ var get = function(i){ return cells[i] ? cells[i].innerHTML.trim() : '—'; };
+ var getText = function(i){ return cells[i] ? cells[i].textContent.trim() : '—'; };
+
+ var html = '' +
+ '
' +
+ '
设备信息
' +
+ '
' +
+ '
日期' + getText(0) + '
' +
+ '
食堂' + getText(1) + '
' +
+ '
餐线名称' + getText(2) + '
' +
+ '
秤台编号' + getText(4) + '
' +
+ '
秤台状态' + get(5) + '
' +
+ '
称台类型' + get(6) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
餐次与时间
' +
+ '
' +
+ '
餐次' + getText(3) + '
' +
+ '
上餐类型' + get(7) + '
' +
+ '
开机时间' + getText(8) + '
' +
+ '
上餐时间' + getText(9) + '
' +
+ '
保鲜时间' + getText(19) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
餐品与计费
' +
+ '
' +
+ '
餐品名称' + getText(10) + '
' +
+ '
餐品单价' + getText(11) + '
' +
+ '
应收金额' + getText(12) + '
' +
+ '
取餐人次' + getText(20) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
重量数据
' +
+ '
' +
+ '
实时重量(kg)' + getText(13) + '
' +
+ '
累计取餐重量' + getText(14) + '
' +
+ '
累计上餐生重(kg)' + getText(15) + '
' +
+ '
累计上餐重量' + getText(16) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
温度监控
' +
+ '
' +
+ '
最高温度' + getText(17) + '
' +
+ '
最低温度' + getText(18) + '
' +
+ '
' +
+ '
';
+
+ Drawer.open('秤台详情 — ' + getText(4), html);
+}
+
+/* ========== 累计汇总抽屉 ========== */
+function showSummaryDetail(row) {
+ var cells = row.querySelectorAll('td');
+ var getText = function(i){ return cells[i] ? cells[i].textContent.trim() : '—'; };
+
+ var html = '' +
+ '
' +
+ '
基本信息
' +
+ '
' +
+ '
统计日期' + getText(0) + '
' +
+ '
食堂' + getText(1) + '
' +
+ '
餐线名称' + getText(2) + '
' +
+ '
餐次' + getText(3) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
餐品与计费
' +
+ '
' +
+ '
餐品数量' + getText(4) + '
' +
+ '
累计应收金额' + getText(7) + '
' +
+ '
取餐人次' + getText(8) + '
' +
+ '
平均取餐重量(g/人)' + getText(9) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
重量数据
' +
+ '
' +
+ '
累计取餐重量(kg)' + getText(5) + '
' +
+ '
累计上餐重量(kg)' + getText(6) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
温度与异常
' +
+ '
' +
+ '
最高温度' + getText(10) + '
' +
+ '
最低温度' + getText(11) + '
' +
+ '
异常次数' + getText(12) + '
' +
+ '
' +
+ '
';
+
+ Drawer.open('累计汇总详情 — ' + getText(2) + ' ' + getText(0), html);
+}
+
+/* ========== 绑定查看/取餐/上餐链接 ========== */
+// Tab1: 实时监控
(function bindDetailLinks() {
const panel = document.querySelectorAll('.tab-panel')[0];
if (!panel) return;
panel.querySelectorAll('tbody tr').forEach(row => {
const cells = row.querySelectorAll('td');
- if (cells.length < 15) return;
- const scaleId = cells[0].textContent.trim();
- // 累计取餐重量 — 第13列(index 12)
- const pickupLink = cells[12] && cells[12].querySelector('.link');
+ if (cells.length < 17) return;
+ const scaleId = cells[4].textContent.trim();
+ // 累计取餐重量 — 第15列(index 14)
+ const pickupLink = cells[14] && cells[14].querySelector('.link');
if (pickupLink) pickupLink.addEventListener('click', () => showPickupDetail(scaleId));
- // 累计上餐重量 — 第15列(index 14)
- const servingLink = cells[14] && cells[14].querySelector('.link');
+ // 累计上餐重量 — 第17列(index 16)
+ const servingLink = cells[16] && cells[16].querySelector('.link');
if (servingLink) servingLink.addEventListener('click', () => showServingDetail(scaleId));
+ // 操作列"查看"按钮 — 最后一列第一个 link
+ const actionsCell = row.querySelector('td.td-actions');
+ if (actionsCell) {
+ const links = actionsCell.querySelectorAll('.link');
+ if (links[0]) links[0].addEventListener('click', function(){ showScaleDetail(row); });
+ }
+ });
+})();
+
+// Tab2: 累计汇总
+(function bindSummaryLinks() {
+ const panel = document.querySelectorAll('.tab-panel')[1];
+ if (!panel) return;
+ panel.querySelectorAll('tbody tr').forEach(row => {
+ if (row.classList.contains('summary-row')) return;
+ const actionsCell = row.querySelector('td.td-actions');
+ if (actionsCell) {
+ const links = actionsCell.querySelectorAll('.link');
+ if (links[0]) links[0].addEventListener('click', function(){ showSummaryDetail(row); });
+ }
+ });
+})();
+
+// Tab3: 累计汇总(按秤台)
+function showScaleSummaryDetail(row) {
+ var cells = row.querySelectorAll('td');
+ var get = function(i){ return cells[i] ? cells[i].innerHTML.trim() : '—'; };
+ var getText = function(i){ return cells[i] ? cells[i].textContent.trim() : '—'; };
+
+ var html = '' +
+ '
' +
+ '
基本信息
' +
+ '
' +
+ '
日期' + getText(0) + '
' +
+ '
食堂' + getText(1) + '
' +
+ '
餐线名称' + getText(2) + '
' +
+ '
餐次' + getText(3) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
设备信息
' +
+ '
' +
+ '
秤台编号' + getText(4) + '
' +
+ '
秤台状态' + get(5) + '
' +
+ '
称台类型' + get(6) + '
' +
+ '
上餐类型' + get(7) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
餐品与计费
' +
+ '
' +
+ '
餐品数量' + getText(8) + '
' +
+ '
累计应收金额' + getText(9) + '
' +
+ '
取餐人次' + getText(15) + '
' +
+ '
平均取餐重量(g/人)' + getText(16) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
重量数据
' +
+ '
' +
+ '
累计取餐重量(kg)' + getText(10) + '
' +
+ '
累计上餐生重(kg)' + getText(11) + '
' +
+ '
累计上餐重量(kg)' + getText(12) + '
' +
+ '
' +
+ '
' +
+ '
' +
+ '
温度与异常
' +
+ '
' +
+ '
最高温度' + getText(13) + '
' +
+ '
最低温度' + getText(14) + '
' +
+ '
异常次数' + getText(17) + '
' +
+ '
' +
+ '
';
+
+ Drawer.open('秤台汇总详情 — ' + getText(4), html);
+}
+
+(function bindScaleSummaryLinks() {
+ const panel = document.querySelectorAll('.tab-panel')[2];
+ if (!panel) return;
+ panel.querySelectorAll('tbody tr').forEach(row => {
+ if (row.classList.contains('summary-row')) return;
+ const actionsCell = row.querySelector('td.td-actions');
+ if (actionsCell) {
+ const links = actionsCell.querySelectorAll('.link');
+ if (links[0]) links[0].addEventListener('click', function(){ showScaleSummaryDetail(row); });
+ }
});
})();
diff --git a/web-admin/nutrition/din-order-pickup.html b/web-admin/nutrition/din-order-pickup.html
index abb7dd4..26df32c 100644
--- a/web-admin/nutrition/din-order-pickup.html
+++ b/web-admin/nutrition/din-order-pickup.html
@@ -116,6 +116,65 @@ tbody tr:hover{background:#F8FBFF;}
thead th:last-child,tbody td.td-actions{position:sticky;right:0;background:#fff;box-shadow:-4px 0 8px rgba(0,0,0,0.04);z-index:2;white-space:nowrap;}
thead th:last-child{background:#FAFAFA;}
tbody tr:hover td.td-actions{background:#F8FBFF;}
+
+/* 餐品详情弹窗 */
+.meal-section{margin-bottom:20px;}
+.meal-section__title{font-size:var(--font-base);font-weight:600;color:var(--text-primary);padding-left:10px;border-left:3px solid var(--primary);margin-bottom:12px;}
+.meal-info-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:10px 24px;margin-bottom:24px;}
+.meal-info-item{display:flex;align-items:center;gap:8px;font-size:var(--font-sm);padding:8px 0;border-bottom:1px dashed #f0f0f0;}
+.meal-info-item__label{color:var(--text-secondary);min-width:72px;flex-shrink:0;}
+.meal-info-item__value{color:var(--text-primary);font-weight:500;}
+.meal-table{width:100%;border-collapse:collapse;margin-top:8px;}
+.meal-table thead th{background:#FAFAFA;padding:10px 16px;text-align:center;font-size:var(--font-sm);color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
+.meal-table tbody td{padding:12px 16px;font-size:var(--font-sm);color:var(--text-primary);border-bottom:1px solid var(--border);text-align:center;}
+.meal-table tbody tr:last-child td{border-bottom:none;font-weight:600;background:#FAFAFA;}
+.meal-table .dish-name{color:var(--primary);cursor:pointer;font-weight:500;}
+.meal-table .dish-name:hover{color:#40a9ff;}
+.tag-scale{display:inline-block;padding:1px 6px;border-radius:3px;font-size:11px;background:#E6F7FF;color:var(--primary);border:1px solid #91D5FF;margin-left:6px;vertical-align:middle;}
+
+/* 历史用餐明细表格 */
+.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);}
@@ -187,13 +246,15 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
-
-
-
+
+
+
+
+
-
+
至
@@ -202,7 +263,6 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
@@ -213,18 +273,18 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
- | 就餐记录号 | 用户 | 部门 | 餐次 | 取餐方式 | 取餐类型 | 人员类别 | 取餐开始时间 | 取餐结束时间 | 取餐总数量 | 营养评分 | 操作 |
+ | 就餐记录号 | 姓名 | 员工编号 | 单位 | 部门 | 餐次 | 取餐方式 | 取餐类型 | 人员类别 | 取餐开始时间 | 取餐结束时间 | 取餐总数量 | 营养评分 | 操作 |
- | M-20260428-001 | 张伟(EMP001) | 研发部 | 午餐 | 点餐取餐 | 正常取餐 | 会员 | 11:02 | 11:08 | 3件 | 88分 | 查看用户信息 |
- | M-20260428-002 | 李娜(EMP002) | 市场部 | 午餐 | 点餐取餐 | 正常取餐 | 会员 | 11:08 | 11:14 | 3件 | 92分 | 查看用户信息 |
- | M-20260428-003 | 王磊(EMP003) | 运营部 | 午餐 | 餐线取餐 | 正常取餐 | 非会员 | 11:15 | 11:20 | 2件 | 68分 | 查看用户信息 |
- | M-20260428-004 | 赵敏(EMP004) | 财务部 | 午餐 | 档口+餐线 | 正常取餐 | 会员 | 11:22 | 11:30 | 3件 | 94分 | 查看用户信息 |
- | M-20260428-005 | 陈刚(EMP005) | 人事部 | 早餐 | 餐线取餐 | 正常取餐 | 非会员 | 07:48 | 07:55 | 3件 | 85分 | 查看用户信息 |
- | M-20260428-006 | 刘芳(EMP006) | 市场部 | 午餐 | 外卖/外带 | 正常取餐 | 会员 | 11:45 | 11:48 | 2件 | 90分 | 查看用户信息 |
- | SP-001-001 | 张运维(EMP101) | 运维部 | 午餐 | 余量取餐 | 余量取餐 | 员工 | 14:05 | 14:06 | 1件 | — | 查看用户信息 |
- | SP-001-003 | 王保安(EMP103) | 安保部 | 午餐 | 余量取餐 | 余量取餐 | 工作人员 | 14:10 | 14:11 | 1件 | — | 查看用户信息 |
- | M-20260428-007 | 林教授 | 外部访客 | 午餐 | 点餐取餐 | 正常取餐 | 外部人员 | 12:10 | 12:18 | 3件 | 86分 | 查看用户信息 |
+ | M-20260428-001 | 张伟 | EMP001 | 长庆油田 | 研发部 | 午餐 | 点餐取餐 | 正常取餐 | 会员 | 11:02 | 11:08 | 3件 | 88分 | 查看用户信息 |
+ | M-20260428-002 | 李娜 | EMP002 | 长庆油田 | 市场部 | 午餐 | 点餐取餐 | 正常取餐 | 会员 | 11:08 | 11:14 | 3件 | 92分 | 查看用户信息 |
+ | M-20260428-003 | 王磊 | EMP003 | 长庆油田 | 运营部 | 午餐 | 餐线取餐 | 正常取餐 | 非会员 | 11:15 | 11:20 | 2件 | 68分 | 查看用户信息 |
+ | M-20260428-004 | 赵敏 | EMP004 | 长庆油田 | 财务部 | 午餐 | 档口+餐线 | 正常取餐 | 会员 | 11:22 | 11:30 | 3件 | 94分 | 查看用户信息 |
+ | M-20260428-005 | 陈刚 | EMP005 | 长庆油田 | 人事部 | 早餐 | 餐线取餐 | 正常取餐 | 非会员 | 07:48 | 07:55 | 3件 | 85分 | 查看用户信息 |
+ | M-20260428-006 | 刘芳 | EMP006 | 长庆油田 | 市场部 | 午餐 | 外卖/外带 | 正常取餐 | 会员 | 11:45 | 11:48 | 2件 | 90分 | 查看用户信息 |
+ | SP-001-001 | 张运维 | EMP101 | 长庆油田 | 运维部 | 午餐 | 余量取餐 | 余量取餐 | 员工 | 14:05 | 14:06 | 1件 | — | 查看用户信息 |
+ | SP-001-003 | 王保安 | — | 长庆油田 | 安保部 | 午餐 | 余量取餐 | 余量取餐 | 工作人员 | 14:10 | 14:11 | 1件 | — | 查看用户信息 |
+ | M-20260428-007 | 林教授 | — | 外部单位 | 外部访客 | 午餐 | 点餐取餐 | 正常取餐 | 外部人员 | 12:10 | 12:18 | 3件 | 86分 | 查看用户信息 |
@@ -274,20 +334,40 @@ const userProfiles = {
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%' },
+ 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},
+ {date:'2026-04-25',meal:'午餐',dishes:'米饭、宫保鸡丁、番茄炒蛋',cal:'928 kcal',score:88},
+ {date:'2026-04-24',meal:'午餐',dishes:'米饭、清蒸鱼、蒜蓉菠菜、番茄蛋花汤',cal:'768 kcal',score:95}
+ ],
+ 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},
+ {date:'2026-04-25',meal:'午餐',dishes:'番茄鱼片、杂粮饭、炒时蔬',cal:'750 kcal',score:91},
+ {date:'2026-04-24',meal:'午餐',dishes:'清蒸鲈鱼、藜麦沙拉、紫菜汤',cal:'690 kcal',score:96}
+ ],
+ 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' }
};
/* 默认档案(其他用户) */
@@ -297,10 +377,20 @@ const defaultProfile = { dept:'—', age:30, gender:'—', height:'170cm', weigh
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-25',meal:'早餐',dishes:'豆浆、油条、茶叶蛋',cal:'450 kcal',score:76},
+ {date:'2026-04-24',meal:'午餐',dishes:'宫保鸡丁、米饭、番茄蛋汤',cal:'790 kcal',score:86},
+ {date:'2026-04-23',meal:'午餐',dishes:'西红柿炒蛋、米饭、炒青菜',cal:'680 kcal',score:88}
+ ],
+ 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:'静态基础' },
@@ -360,34 +450,52 @@ function buildProfileHTML(name, p) {
数据来源${p.source}
-
常点菜品${p.favDish}
-
系统推荐${p.recDish}
-
忌口菜品${p.avoidDish}
-
评分最高${p.topRate}
-
复购冠军${p.repurchase}
+ mom: `
+
+
+
+
+
思乡菜清单
${p.momList.split('、').map(d=>''+d+'').join('')}
+
+
`,
- mom: `
-
家乡${p.hometown}
-
妈妈味道标签${p.momTag}
-
思乡菜清单${p.momList}
-
关联记忆${p.memory}
-
推荐尝试${p.recTry}
-
`,
- model: `
-
模型版本${p.modelVer}
-
生成时间${p.modelTime}
-
推荐热量${p.recCal}
-
营养侧重${p.nutriFocus}
-
风险预警${p.risk}
-
个性标签${p.tags}
-
模型置信度${p.confidence}
-
`
+ model: `
+
+
+
+
+
+
+
风险预警
${p.risk==='无风险'?'✅ ':''} ${p.risk}
+
+
+ `
};
const tabs = tabDefs.map((t, i) => `
${t.label}
`).join('');
const panelsHtml = tabDefs.map((t, i) => `
${panels[t.key]}
`).join('');
@@ -416,6 +524,121 @@ document.querySelectorAll('tbody tr').forEach(row => {
link.addEventListener('click', () => showUserProfile(nameCell.textContent));
}
});
+
+/* ========== 取餐详情弹窗 ========== */
+const mealData = {
+ 'M-20260428-001': [
+ { name:'清炒生菜', type:'秤', weight:133.0, cal:24.6, carb:1.6, fat:1.4, protein:2.2 },
+ { name:'西红柿鸡蛋', type:'秤', weight:114.0, cal:94.5, carb:4.7, fat:5.1, protein:8.4 },
+ { name:'辣子鸡丁', type:'秤', weight:79.0, cal:92.5, carb:3.3, fat:4.6, protein:9.8 }
+ ],
+ 'M-20260428-002': [
+ { name:'藜麦沙拉', type:'秤', weight:150.0, cal:68.0, carb:12.5, fat:1.8, protein:3.2 },
+ { name:'清蒸鲈鱼', type:'秤', weight:120.0, cal:112.0, carb:0.5, fat:4.2, protein:18.6 },
+ { name:'蒜蓉西兰花', type:'秤', weight:95.0, cal:32.0, carb:4.1, fat:1.2, protein:2.8 }
+ ],
+ 'M-20260428-003': [
+ { name:'红烧肉', type:'秤', weight:85.0, cal:210.5, carb:5.2, fat:15.3, protein:12.1 },
+ { name:'米饭', type:'秤', weight:200.0, cal:232.0, carb:50.8, fat:0.6, protein:4.6 }
+ ],
+ 'M-20260428-004': [
+ { name:'宫保鸡丁', type:'秤', weight:110.0, cal:145.0, carb:8.2, fat:7.5, protein:12.3 },
+ { name:'番茄牛腩', type:'秤', weight:130.0, cal:125.0, carb:6.8, fat:5.2, protein:14.5 },
+ { name:'杂粮饭', type:'秤', weight:180.0, cal:198.0, carb:42.0, fat:1.2, protein:5.8 }
+ ],
+ 'M-20260428-005': [
+ { name:'小米粥', type:'秤', weight:250.0, cal:115.0, carb:24.5, fat:0.8, protein:2.4 },
+ { name:'煎蛋', type:'秤', weight:60.0, cal:90.0, carb:0.6, fat:7.0, protein:6.3 },
+ { name:'全麦馒头', type:'秤', weight:80.0, cal:176.0, carb:35.2, fat:1.5, protein:6.8 }
+ ],
+ 'M-20260428-006': [
+ { name:'鸡胸肉沙拉', type:'秤', weight:180.0, cal:145.0, carb:5.2, fat:3.8, protein:22.5 },
+ { name:'玉米浓汤', type:'秤', weight:200.0, cal:88.0, carb:16.0, fat:2.1, protein:2.8 }
+ ],
+ 'SP-001-001': [
+ { name:'余量套餐A', type:'秤', weight:220.0, cal:185.0, carb:28.0, fat:4.5, protein:9.2 }
+ ],
+ 'SP-001-003': [
+ { name:'余量套餐B', type:'秤', weight:195.0, cal:168.0, carb:25.5, fat:3.8, protein:8.5 }
+ ],
+ 'M-20260428-007': [
+ { name:'糖醋里脊', type:'秤', weight:95.0, cal:178.0, carb:14.2, fat:8.5, protein:11.8 },
+ { name:'蛋花汤', type:'秤', weight:200.0, cal:35.0, carb:1.2, fat:1.5, protein:3.8 },
+ { name:'米饭', type:'秤', weight:180.0, cal:208.8, carb:45.7, fat:0.5, protein:4.1 }
+ ]
+};
+
+function showMealDetail(row) {
+ const cells = row.querySelectorAll('td');
+ const recordId = cells[0].textContent;
+ const name = cells[1].textContent;
+ const empNo = cells[2].textContent;
+ const unit = cells[3].textContent;
+ const dept = cells[4].textContent;
+ const mealTime = cells[5].textContent;
+ const pickupMethod = cells[6].textContent.trim();
+ const pickupType = cells[7].textContent.trim();
+ const startTime = cells[9].textContent;
+ const endTime = cells[10].textContent;
+
+ const items = mealData[recordId] || [];
+ const totalWeight = items.reduce((s, i) => s + i.weight, 0);
+ const totalCal = items.reduce((s, i) => s + i.cal, 0);
+ const totalCarb = items.reduce((s, i) => s + i.carb, 0);
+ const totalFat = items.reduce((s, i) => s + i.fat, 0);
+ const totalProtein = items.reduce((s, i) => s + i.protein, 0);
+
+ const infoHtml = `
+
基本信息
+
+
就餐记录号${recordId}
+
姓名${name}
+
员工编号${empNo}
+
单位${unit}
+
部门${dept}
+
餐次${mealTime}
+
取餐方式${pickupMethod}
+
取餐类型${pickupType}
+
取餐时间${startTime} ~ ${endTime}
+
+
`;
+
+ const tableRows = items.map(i => `
+ | ${i.name} |
+ ${i.weight.toFixed(1)} |
+ ${i.cal.toFixed(1)} |
+ ${i.carb.toFixed(1)} |
+ ${i.fat.toFixed(1)} |
+ ${i.protein.toFixed(1)} |
+
`).join('');
+
+ const summaryRow = `
+ | 合计 |
+ ${totalWeight.toFixed(1)}克 |
+ ${totalCal.toFixed(1)}千卡 |
+ ${totalCarb.toFixed(1)}克 |
+ ${totalFat.toFixed(1)}克 |
+ ${totalProtein.toFixed(1)}克 |
+
`;
+
+ const tableHtml = `
+
餐品列表
+
+ | 餐品名称 | 重量(克) | 热量(千卡) | 碳水化合物(克) | 脂肪(克) | 蛋白质(克) |
+ ${tableRows}${summaryRow}
+
+
`;
+
+ Modal.open('取餐详情 — ' + name, infoHtml + tableHtml);
+}
+
+/* 绑定"取餐总数量"列点击事件 */
+document.querySelectorAll('tbody tr').forEach(row => {
+ const quantityLink = row.querySelector('td:nth-child(12) .link');
+ if (quantityLink) {
+ quantityLink.addEventListener('click', () => showMealDetail(row));
+ }
+});