feat: 健康服务APP中新增营养师角色 ,设计营养师工作台页面原型

This commit is contained in:
fengpu
2026-09-18 17:45:29 +08:00
parent 63407a20c2
commit 71ddc7fa0a
21 changed files with 3931 additions and 12 deletions
+2 -1
View File
@@ -129,7 +129,8 @@ function initTabLinks() {
professional: '../professional',
operator: '../operator',
onsite: '../onsite',
admin: '../admin'
admin: '../admin',
nutritionist: '../nutritionist'
};
var base = roleBaseMap[role] || '../expert';
document.getElementById('link-workbench').href = base + '/workbench/index.html';
+2 -1
View File
@@ -265,7 +265,8 @@ function initTabLinks() {
professional: '../professional',
operator: '../operator',
onsite: '../onsite',
admin: '../admin'
admin: '../admin',
nutritionist: '../nutritionist'
};
var base = roleBaseMap[role] || '../expert';
document.getElementById('link-workbench').href = base + '/workbench/index.html';
@@ -0,0 +1,159 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>营养知识详情 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="window.location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title" id="kd-nav-title">知识详情</span>
</div>
<div class="scroll-content" style="padding:16px;">
<div id="kd-content" style="background:#fff;border-radius:16px;padding:20px;box-shadow:0 1px 6px rgba(0,0,0,0.06);"></div>
<div style="height:16px;"></div>
</div>
</div>
<script>
/* 营养知识库数据集合 */
var KB_DATA = {
'pyramid': {
icon: '🥗', bg: '#f6ffed', title: '中国居民膳食宝塔(2022', cat: '膳食营养', date: '2026-03-15',
summary: '膳食宝塔是中国居民平衡膳食的指导框架,将食物分为五大类,按推荐摄入量由多到少排列,是制定食谱与营养指导的基础依据。',
items: [
{ color: '#52c41a', name: '谷薯类', desc: '每日 250-400g,其中全谷物和杂豆 50-150g,薯类 50-100g。谷类是膳食能量的主要来源,建议粗细搭配。' },
{ color: '#1677ff', name: '蔬菜水果', desc: '每日蔬菜 300-500g(深色蔬菜占一半),水果 200-350g。保证维生素、矿物质和膳食纤维摄入。' },
{ color: '#fa8c16', name: '畜禽鱼蛋', desc: '每日畜禽肉 40-75g、水产品 40-75g、蛋类 40-50g。优先选择鱼禽,减少肥肉和加工肉制品。' },
{ color: '#722ed1', name: '奶豆坚果', desc: '每日奶及奶制品 300-500g,大豆及坚果 25-35g。是优质蛋白和钙的重要来源。' }
]
},
'macro': {
icon: '🍚', bg: '#e6f4ff', title: '三大营养素摄入指南', cat: '膳食营养', date: '2026-03-10',
summary: '蛋白质、脂肪、碳水化合物是人体必需的三大产能营养素,合理配比是维持健康体重和代谢功能的关键。',
items: [
{ color: '#1677ff', name: '碳水化合物', desc: '供能比 50-65%。优先选择全谷物、杂豆、薯类等复合碳水,限制添加糖摄入(每日<25g)。' },
{ color: '#52c41a', name: '蛋白质', desc: '供能比 15-20%。优质蛋白来源包括鱼、禽、蛋、奶、豆制品。轻体力成人每日约 1.0g/kg 体重。' },
{ color: '#fa8c16', name: '脂肪', desc: '供能比 20-30%。优先不饱和脂肪酸(橄榄油、坚果、鱼类),限制饱和脂肪(<10%)和反式脂肪(<1%)。' }
]
},
'vitamin': {
icon: '🍎', bg: '#fff7e6', title: '维生素与矿物质需求', cat: '膳食营养', date: '2026-03-05',
summary: '维生素和矿物质虽然需求量小,却是维持正常生理功能不可或缺的微量营养素,缺乏时会出现特定症状。',
items: [
{ color: '#fa8c16', name: '维生素 C', desc: '每日 100mg。来源:新鲜果蔬(猕猴桃、橙子、青椒)。缺乏可致牙龈出血、伤口愈合不良。' },
{ color: '#1677ff', name: '钙', desc: '每日 800-1000mg。来源:奶制品、豆制品、绿叶菜。缺乏可致骨质疏松、肌肉痉挛。' },
{ color: '#ff4d4f', name: '铁', desc: '男性每日 12mg、女性 20mg。来源:动物肝脏、瘦肉、动物血。缺乏可致缺铁性贫血。' }
]
},
'fatloss': {
icon: '🏃', bg: '#f6ffed', title: '科学减脂饮食原则', cat: '减脂控糖', date: '2026-02-28',
summary: '减脂的核心是热量缺口,但必须在保证营养均衡的前提下进行,避免极端节食导致肌肉流失和代谢下降。',
items: [
{ color: '#52c41a', name: '热量缺口', desc: '每日热量缺口 300-500kcal,减重速度以每周 0.5-1kg 为宜。避免过度节食(不低于基础代谢)。' },
{ color: '#1677ff', name: '高蛋白饮食', desc: '蛋白质供能比可提高至 20-30%,增加饱腹感并减少肌肉流失。选择鸡胸、鱼虾、蛋白、豆制品。' },
{ color: '#fa8c16', name: '控制精制碳水', desc: '减少白米饭、白面包等精制碳水,替换为全谷物、杂豆,稳定血糖、增强饱腹感。' }
]
},
'lowgi': {
icon: '🍬', bg: '#e6f4ff', title: '低 GI 饮食控糖策略', cat: '减脂控糖', date: '2026-02-20',
summary: '低升糖指数(GI)饮食可延缓血糖上升速度,是糖尿病管理和预防的重要饮食策略。',
items: [
{ color: '#1677ff', name: '食物选择', desc: '优先低 GI 食物:全谷物、豆类、大部分蔬菜、低糖水果。避免精制米面、含糖饮料、糕点。' },
{ color: '#52c41a', name: '进餐顺序', desc: '先吃蔬菜和蛋白质,再吃主食,可显著降低餐后血糖峰值,改善血糖控制。' },
{ color: '#fa8c16', name: '烹饪方式', desc: '主食不要煮得过烂,粗细搭配;避免勾芡、油炸;控制每餐主食总量,少量多餐。' }
]
},
'hyperlipid': {
icon: '🫀', bg: '#fff7e6', title: '高血脂饮食管理', cat: '慢性病营养', date: '2026-03-01',
summary: '高血脂是动脉粥样硬化的重要危险因素,饮食管理重点是限制饱和脂肪和反式脂肪,增加膳食纤维。',
items: [
{ color: '#ff4d4f', name: '限制饱和脂肪', desc: '每日饱和脂肪<总能量10%。减少肥肉、动物内脏、黄油、椰子油,选择瘦肉和低脂奶制品。' },
{ color: '#fa8c16', name: '杜绝反式脂肪', desc: '避免人造黄油、植脂末、油炸食品、起酥点心。反式脂肪显著升高 LDL-C,增加心血管风险。' },
{ color: '#52c41a', name: '增加膳食纤维', desc: '每日 25-30g 膳食纤维。多吃燕麦、豆类、蔬菜、水果,可降低胆固醇吸收。' }
]
},
'uric': {
icon: '🦴', bg: '#fff1f0', title: '高尿酸人群饮食禁忌', cat: '慢性病营养', date: '2026-02-15',
summary: '高尿酸血症是痛风的生化基础,通过限制高嘌呤食物、增加水分摄入可有效降低尿酸水平。',
items: [
{ color: '#ff4d4f', name: '限制高嘌呤食物', desc: '避免动物内脏、浓肉汤、海鲜(沙丁鱼、贝类)、啤酒。嘌呤>150mg/100g 的食物应严格限制。' },
{ color: '#fa8c16', name: '低嘌呤食物选择', desc: '优先选择蛋类、奶类、蔬菜、水果、谷物。肉类焯水后再烹饪可减少嘌呤含量。' },
{ color: '#1677ff', name: '多饮水', desc: '每日饮水 2000ml 以上,促进尿酸排泄。避免含糖饮料和酒精,尤其是啤酒和白酒。' }
]
},
'safety': {
icon: '🧪', bg: '#f6ffed', title: '食品添加剂使用规范', cat: '食品安全', date: '2026-02-25',
summary: '食品添加剂在合规使用范围内是安全的,了解常见添加剂的用途和限量有助于科学评估食品安全。',
items: [
{ color: '#52c41a', name: '防腐剂', desc: '如苯甲酸钠、山梨酸钾。用于抑制微生物生长,延长保质期。在规定限量内使用安全。' },
{ color: '#1677ff', name: '抗氧化剂', desc: '如 BHA、BHT、维生素 E。防止油脂氧化酸败,常用于食用油和坚果制品。' },
{ color: '#fa8c16', name: '着色剂', desc: '如焦糖色、胭脂红。用于改善食品色泽。天然色素(姜黄、红曲)安全性更高。' }
]
},
'trace': {
icon: '🔍', bg: '#e6f4ff', title: '食材溯源与质量安全', cat: '食品安全', date: '2026-02-10',
summary: '食材溯源是通过溯源码记录食材从种植养殖、加工、运输到餐桌的全链路信息,保障食品安全可追溯。',
items: [
{ color: '#1677ff', name: '溯源码体系', desc: '每一批次食材赋予唯一溯源码,关联产地、检测报告、流转节点,实现一物一码、全程可查。' },
{ color: '#52c41a', name: '质量检测节点', desc: '毛菜入库时进行农残/重金属/微生物检测,净菜加工后二次质检,合格品方可进入厨房。' },
{ color: '#fa8c16', name: '异常处置', desc: '检测不合格的食材立即隔离并追溯同批次产品,防止问题食材流入餐桌。' }
]
}
};
/* 页面加载时根据URL参数渲染知识详情 */
function renderDetail() {
var params = new URLSearchParams(window.location.search);
var key = params.get('key') || 'pyramid';
var d = KB_DATA[key];
if (!d) d = KB_DATA['pyramid'];
document.getElementById('kd-nav-title').textContent = d.title;
var itemsHtml = d.items.map(function(it) {
return '<div style="background:#f7f8fa;border-radius:10px;padding:14px;margin-bottom:12px;">' +
'<div style="font-size:13px;font-weight:600;color:' + it.color + ';margin-bottom:6px;">' + it.name + '</div>' +
'<div style="font-size:13px;color:#444;line-height:1.7;">' + it.desc + '</div>' +
'</div>';
}).join('');
document.getElementById('kd-content').innerHTML =
'<div style="display:flex;align-items:center;gap:12px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #f5f5f5;">' +
'<div style="width:48px;height:48px;border-radius:12px;background:' + d.bg + ';display:flex;align-items:center;justify-content:center;font-size:24px;">' + d.icon + '</div>' +
'<div><div style="font-size:17px;font-weight:700;color:#1a1a1a;">' + d.title + '</div><div style="font-size:12px;color:#999;margin-top:3px;">' + d.cat + ' · 更新于 ' + d.date + '</div></div>' +
'</div>' +
'<div style="font-size:15px;font-weight:700;color:#1a1a1a;margin-bottom:8px;">概述</div>' +
'<div style="font-size:14px;color:#444;line-height:1.8;margin-bottom:16px;">' + d.summary + '</div>' +
'<div style="font-size:15px;font-weight:700;color:#1a1a1a;margin-bottom:8px;">主要内容</div>' +
itemsHtml;
}
renderDetail();
</script>
</body>
</html>
@@ -0,0 +1,153 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>营养师 - 知识库 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.sub-tabs { display: flex; gap: 8px; padding: 10px 16px; background: #fff; flex-shrink: 0; }
.sub-tab { font-size: 12px; padding: 4px 14px; border-radius: 16px; background: #f5f5f5; color: #666; cursor: pointer; transition: all 0.2s; white-space: nowrap; }
.sub-tab.active { background: #e6f4ff; color: #1677ff; font-weight: 600; }
.tab-bar { height: 83px; background: #fff; border-top: 1px solid #e8e8e8; display: flex; align-items: flex-start; padding-top: 8px; flex-shrink: 0; }
.tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; padding: 4px 0; position: relative; text-decoration: none; }
.tab-item .tab-icon { font-size: 22px; line-height: 1; }
.tab-item .tab-label { font-size: 10px; color: #999; font-weight: 500; }
.tab-item.active .tab-label { color: #1677ff; }
.tab-badge { position: absolute; top: 2px; right: 18px; background: #ff4d4f; color: #fff; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 4px; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 蓝色渐变头部 -->
<div style="background:linear-gradient(135deg,#1677ff,#0958d9);padding:16px 20px 20px;flex-shrink:0;">
<div style="color:rgba(255,255,255,0.75);font-size:12px;margin-bottom:2px;">营养专业参考</div>
<div style="color:#fff;font-size:20px;font-weight:700;">知识库</div>
</div>
<!-- 子分类Tab -->
<div class="sub-tabs">
<div class="sub-tab active" onclick="switchKbTab(this,'kb-diet')">膳食营养</div>
<div class="sub-tab" onclick="switchKbTab(this,'kb-weight')">减脂控糖</div>
<div class="sub-tab" onclick="switchKbTab(this,'kb-chronic')">慢性病营养</div>
<div class="sub-tab" onclick="switchKbTab(this,'kb-safe')">食品安全</div>
</div>
<div class="scroll-content">
<!-- 膳食营养 -->
<div id="kb-diet">
<div style="padding:12px 16px 0;">
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('pyramid')">
<div style="width:44px;height:44px;border-radius:10px;background:#f6ffed;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🥗</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">中国居民膳食宝塔(2022</div><div style="font-size:12px;color:#999;margin-top:3px;">五大类食物推荐摄入量与搭配原则</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('macro')">
<div style="width:44px;height:44px;border-radius:10px;background:#e6f4ff;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🍚</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">三大营养素摄入指南</div><div style="font-size:12px;color:#999;margin-top:3px;">蛋白质、脂肪、碳水化合物的合理配比</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('vitamin')">
<div style="width:44px;height:44px;border-radius:10px;background:#fff7e6;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🍎</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">维生素与矿物质需求</div><div style="font-size:12px;color:#999;margin-top:3px;">常见微量营养素的食物来源与缺乏症状</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 减脂控糖 -->
<div id="kb-weight" style="display:none;">
<div style="padding:12px 16px 0;">
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('fatloss')">
<div style="width:44px;height:44px;border-radius:10px;background:#f6ffed;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🏃</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">科学减脂饮食原则</div><div style="font-size:12px;color:#999;margin-top:3px;">热量缺口与营养均衡的减脂方案</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('lowgi')">
<div style="width:44px;height:44px;border-radius:10px;background:#e6f4ff;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🍬</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">低 GI 饮食控糖策略</div><div style="font-size:12px;color:#999;margin-top:3px;">低升糖指数食物选择与餐序调整</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 慢性病营养 -->
<div id="kb-chronic" style="display:none;">
<div style="padding:12px 16px 0;">
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('hyperlipid')">
<div style="width:44px;height:44px;border-radius:10px;background:#fff7e6;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🫀</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">高血脂饮食管理</div><div style="font-size:12px;color:#999;margin-top:3px;">限制饱和脂肪与反式脂肪的摄入</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('uric')">
<div style="width:44px;height:44px;border-radius:10px;background:#fff1f0;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🦴</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">高尿酸人群饮食禁忌</div><div style="font-size:12px;color:#999;margin-top:3px;">嘌呤含量分级与低嘌呤饮食建议</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 食品安全 -->
<div id="kb-safe" style="display:none;">
<div style="padding:12px 16px 0;">
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('safety')">
<div style="width:44px;height:44px;border-radius:10px;background:#f6ffed;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🧪</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">食品添加剂使用规范</div><div style="font-size:12px;color:#999;margin-top:3px;">常见添加剂的安全性与使用限量</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div style="background:#fff;border-radius:10px;padding:12px 14px;display:flex;align-items:center;gap:10px;box-shadow:0 1px 4px rgba(0,0,0,0.06);margin-bottom:10px;cursor:pointer;" onclick="goDetail('trace')">
<div style="width:44px;height:44px;border-radius:10px;background:#e6f4ff;display:flex;align-items:center;justify-content:center;font-size:22px;flex-shrink:0;">🔍</div>
<div style="flex:1;"><div style="font-size:14px;font-weight:600;color:#1a1a1a;">食材溯源与质量安全</div><div style="font-size:12px;color:#999;margin-top:3px;">从田间到餐桌的全链路安全把控</div></div>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<div style="height:16px;"></div>
</div>
</div>
<!-- 底部Tab栏 -->
<div class="tab-bar">
<a class="tab-item" href="../workbench/index.html"><span class="tab-icon">🏥</span><span class="tab-label">工作台</span><span class="tab-badge">2</span></a>
<a class="tab-item active" href="./index.html"><span class="tab-icon">📚</span><span class="tab-label">知识库</span></a>
<a class="tab-item" href="../../ai-assistant/index.html"><span class="tab-icon">🤖</span><span class="tab-label">AI助手</span></a>
<a class="tab-item" href="../../message/index.html"><span class="tab-icon">💬</span><span class="tab-label">消息</span><span class="tab-badge">2</span></a>
<a class="tab-item" href="../profile/index.html"><span class="tab-icon">👤</span><span class="tab-label">我的</span></a>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* 切换知识库分类Tab */
function switchKbTab(el, panelId) {
el.closest('.sub-tabs').querySelectorAll('.sub-tab').forEach(function(t) { t.classList.remove('active'); });
el.classList.add('active');
['kb-diet','kb-weight','kb-chronic','kb-safe'].forEach(function(id) {
document.getElementById(id).style.display = id === panelId ? 'block' : 'none';
});
}
/* 跳转到知识详情页 */
function goDetail(key) {
window.location.href = './detail.html?key=' + key;
}
</script>
</body>
</html>
@@ -0,0 +1,82 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师 - 修改密码 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.btn-primary { background: #1677ff; color: #fff; border: none; border-radius: 10px; padding: 12px 24px; font-size: 15px; font-weight: 600; cursor: pointer; width: 100%; }
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">修改密码</span>
</div>
<div class="scroll-content" style="padding:16px;">
<div style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:20px;">
<div style="display:flex;align-items:center;padding:14px 16px;border-bottom:1px solid #f5f5f5;">
<span style="font-size:14px;color:#999;width:80px;flex-shrink:0;">当前密码</span>
<input type="password" placeholder="请输入当前密码" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
<div style="display:flex;align-items:center;padding:14px 16px;border-bottom:1px solid #f5f5f5;">
<span style="font-size:14px;color:#999;width:80px;flex-shrink:0;">新密码</span>
<input type="password" placeholder="请输入新密码" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
<div style="display:flex;align-items:center;padding:14px 16px;">
<span style="font-size:14px;color:#999;width:80px;flex-shrink:0;">确认新密码</span>
<input type="password" placeholder="再次输入新密码" style="flex:1;border:none;font-size:14px;color:#1a1a1a;outline:none;text-align:right;" />
</div>
</div>
<button onclick="openModal('modal-pwd-saved')" class="btn-primary">保存修改</button>
</div>
<div id="modal-pwd-saved" class="modal-center">
<div class="modal-box">
<div class="modal-title">修改成功</div>
<div class="modal-body">密码已更新,下次登录请使用新密码。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-pwd-saved');location.href='./index.html'" style="color:#1677ff;font-weight:600;flex:1;padding:14px;font-size:16px;cursor:pointer;background:none;border:none;">确定</button>
</div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
</script>
</body>
</html>
@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师 - 个人信息设置 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.nav-right { margin-left: auto; color: #1677ff; font-size: 14px; cursor: pointer; background: none; border: none; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">个人信息设置</span>
<button class="nav-right">保存</button>
</div>
<div class="scroll-content" style="padding:16px;">
<!-- 头像区 -->
<div style="background:#fff;border-radius:12px;padding:20px;margin-bottom:12px;text-align:center;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="position:relative;display:inline-block;">
<div style="width:80px;height:80px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:40px;">🥗</div>
<div style="position:absolute;bottom:0;right:0;width:26px;height:26px;background:#1677ff;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:13px;border:2px solid #fff;cursor:pointer;">📷</div>
</div>
<div style="font-size:13px;color:#999;margin-top:10px;">点击更换头像</div>
</div>
<!-- 擅长领域 -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">擅长领域</div>
<div style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:16px;">
<div style="display:flex;flex-wrap:wrap;gap:8px;">
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;border:1px solid #1677ff;cursor:pointer;">减脂</div>
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;border:1px solid #1677ff;cursor:pointer;">控糖</div>
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#1677ff;color:#fff;border:1px solid #1677ff;cursor:pointer;">增肌</div>
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;border:1px solid #e8e8e8;cursor:pointer;">高血脂</div>
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;border:1px solid #e8e8e8;cursor:pointer;">高尿酸</div>
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;border:1px solid #e8e8e8;cursor:pointer;">术后营养</div>
<div onclick="toggleTag(this)" style="padding:6px 14px;border-radius:16px;font-size:13px;background:#f5f5f5;color:#666;border:1px solid #e8e8e8;cursor:pointer;">孕期营养</div>
</div>
<div style="font-size:11px;color:#bbb;margin-top:10px;">点击标签切换选中状态</div>
</div>
<!-- 个人简介 -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">个人简介</div>
<div style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:16px;">
<textarea style="width:100%;border:none;font-size:14px;color:#1a1a1a;outline:none;resize:none;line-height:1.7;background:transparent;" rows="4" placeholder="请输入个人简介...">注册营养师,从事营养健康管理工作 8 年,擅长体重管理、慢性病营养干预与个性化食谱制定,累计服务员工 2000 余人次。</textarea>
<div style="text-align:right;font-size:11px;color:#bbb;">已输入 68/300 字</div>
</div>
<!-- 职业经历 -->
<div style="font-size:13px;font-weight:600;color:#999;margin:0 4px 8px;">职业经历</div>
<div style="background:#fff;border-radius:12px;padding:14px 16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:20px;">
<textarea style="width:100%;border:none;font-size:14px;color:#1a1a1a;outline:none;resize:none;line-height:1.7;background:transparent;" rows="4" placeholder="请描述您的职业经历..."></textarea>
<div style="text-align:right;font-size:11px;color:#bbb;">已输入 62/300 字</div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* 切换擅长领域标签选中状态 */
function toggleTag(el) {
var isOn = el.style.background === 'rgb(22, 119, 255)' || el.style.background === '#1677ff';
el.style.background = isOn ? '#f5f5f5' : '#1677ff';
el.style.color = isOn ? '#666' : '#fff';
el.style.borderColor = isOn ? '#e8e8e8' : '#1677ff';
}
</script>
</body>
</html>
@@ -0,0 +1,155 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师 - 个人中心 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
.tab-bar { height: 83px; background: #fff; border-top: 1px solid #e8e8e8; display: flex; align-items: flex-start; padding-top: 8px; flex-shrink: 0; }
.tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; padding: 4px 0; position: relative; }
.tab-item .tab-icon { font-size: 22px; line-height: 1; }
.tab-item .tab-label { font-size: 10px; color: #999; font-weight: 500; }
.tab-item.active .tab-label { color: #1677ff; }
.tab-badge { position: absolute; top: 2px; right: 18px; background: #ff4d4f; color: #fff; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 4px; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar" style="background:transparent;position:absolute;top:0;left:0;right:0;z-index:10;">
<span class="time" style="color:#fff;">9:41</span>
<div class="icons" style="color:#fff;"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 蓝色渐变头部 -->
<div style="background:linear-gradient(135deg,#1677ff,#0958d9);padding:30px 20px 24px;flex-shrink:0;padding-top:60px;">
<div style="display:flex;align-items:center;gap:16px;">
<div style="width:68px;height:68px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:34px;border:3px solid rgba(255,255,255,0.5);">🥗</div>
<div>
<div style="color:#fff;font-size:20px;font-weight:700;">李静</div>
<div style="color:rgba(255,255,255,0.8);font-size:13px;margin-top:3px;">注册营养师</div>
<div style="color:rgba(255,255,255,0.65);font-size:12px;margin-top:2px;">健康管理科</div>
</div>
<!-- 服务中按钮 -->
<button onclick="togglePause()" id="pause-btn-mine" style="margin-left:auto;display:flex;align-items:center;gap:6px;background:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4);border-radius:20px;padding:6px 12px;color:#fff;font-size:12px;cursor:pointer;">
<span style="width:7px;height:7px;border-radius:50%;background:#52c41a;display:inline-block;"></span><span id="pause-text">咨询已开启</span>
</button>
</div>
</div>
<!-- 功能列表滚动区域 -->
<div class="scroll-content" style="padding:12px 16px;">
<div style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:12px;">
<div onclick="location.href='./stats.html'" style="display:flex;align-items:center;padding:16px;cursor:pointer;border-bottom:1px solid #f5f5f5;">
<span style="font-size:18px;margin-right:12px;">📊</span><span style="font-size:15px;color:#1a1a1a;flex:1;">营养咨询统计</span>
<span style="font-size:13px;color:#1677ff;margin-right:8px;">今日 12 次</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div onclick="location.href='./schedule.html'" style="display:flex;align-items:center;padding:16px;cursor:pointer;border-bottom:1px solid #f5f5f5;">
<span style="font-size:18px;margin-right:12px;">📅</span><span style="font-size:15px;color:#1a1a1a;flex:1;">排班设置</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div onclick="location.href='./edit-profile.html'" style="display:flex;align-items:center;padding:16px;cursor:pointer;">
<span style="font-size:18px;margin-right:12px;">👤</span><span style="font-size:15px;color:#1a1a1a;flex:1;">个人信息设置</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<div style="background:#fff;border-radius:12px;overflow:hidden;box-shadow:0 1px 6px rgba(0,0,0,0.06);margin-bottom:12px;">
<div onclick="location.href='./change-pwd.html'" style="display:flex;align-items:center;padding:16px;border-bottom:1px solid #f5f5f5;cursor:pointer;">
<span style="font-size:18px;margin-right:12px;">🔒</span><span style="font-size:15px;color:#1a1a1a;flex:1;">修改密码</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
<div style="display:flex;align-items:center;padding:16px;">
<span style="font-size:18px;margin-right:12px;"></span><span style="font-size:15px;color:#1a1a1a;flex:1;">关于我们</span>
<svg width="7" height="12" viewBox="0 0 7 12" fill="none" stroke="#ccc" stroke-width="1.5"><path d="M1 1l5 5-5 5"/></svg>
</div>
</div>
<button onclick="openModal('modal-logout')" style="width:100%;padding:14px;background:#fff;color:#ff4d4f;border:none;border-radius:12px;font-size:15px;font-weight:600;cursor:pointer;box-shadow:0 1px 6px rgba(0,0,0,0.06);">退出登录</button>
</div>
<!-- 退出确认弹窗 -->
<div id="modal-logout" class="modal-center">
<div class="modal-box">
<div class="modal-title">退出登录</div>
<div class="modal-body">确认退出当前账号?</div>
<div class="modal-actions">
<button onclick="closeModal('modal-logout')">取消</button>
<button onclick="closeModal('modal-logout')" style="color:#ff4d4f;">确认退出</button>
</div>
</div>
</div>
<!-- 咨询状态切换确认弹窗 -->
<div id="modal-pause" class="modal-center">
<div class="modal-box">
<div class="modal-title" id="pause-modal-title">关闭咨询</div>
<div class="modal-body" id="pause-modal-body">是否要关闭营养咨询?关闭后,员工无法发起营养咨询。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-pause')">取消</button>
<button onclick="confirmTogglePause()">确认</button>
</div>
</div>
</div>
<!-- 底部Tab栏,我的为active状态 -->
<div class="tab-bar">
<div class="tab-item" onclick="location.href='../workbench/index.html'"><span class="tab-icon">🏥</span><span class="tab-label">工作台</span><span class="tab-badge">2</span></div>
<div class="tab-item" onclick="location.href='../knowledge/index.html'"><span class="tab-icon">📚</span><span class="tab-label">知识库</span></div>
<div class="tab-item" onclick="location.href='../../ai-assistant/index.html'"><span class="tab-icon">🤖</span><span class="tab-label">AI助手</span></div>
<div class="tab-item" onclick="location.href='../../message/index.html'"><span class="tab-icon">💬</span><span class="tab-label">消息</span><span class="tab-badge">2</span></div>
<div class="tab-item active" onclick="location.href='./index.html'"><span class="tab-icon">👤</span><span class="tab-label">我的</span></div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
let isPaused = false;
function togglePause() {
var title = isPaused ? '开启咨询' : '关闭咨询';
var body = isPaused ? '是否要开启营养咨询?开启后,员工可发起营养咨询。' : '是否要关闭营养咨询?关闭后,员工无法发起营养咨询。';
document.getElementById('pause-modal-title').textContent = title;
document.getElementById('pause-modal-body').textContent = body;
openModal('modal-pause');
}
function confirmTogglePause() {
isPaused = !isPaused;
var bg = isPaused ? '#ff4d4f' : '#52c41a';
var text = isPaused ? '咨询已关闭' : '咨询已开启';
var mineBtn = document.getElementById('pause-btn-mine');
if (mineBtn) {
var dot = mineBtn.querySelector('span');
if (dot) dot.style.background = bg;
var pauseText = document.getElementById('pause-text');
if (pauseText) pauseText.textContent = text;
}
closeModal('modal-pause');
}
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
</script>
</body>
</html>
@@ -0,0 +1,183 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师 - 排班设置 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.nav-right { margin-left: auto; color: #1677ff; font-size: 14px; cursor: pointer; background: none; border: none; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.toggle { position: relative; width: 44px; height: 24px; border-radius: 12px; background: #e0e0e0; cursor: pointer; transition: background .2s; flex-shrink: 0; }
.toggle.on { background: #4cd964; }
.toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2); transition: transform .2s; }
.toggle.on::after { transform: translateX(20px); }
.day-card { background: #fff; border-radius: 12px; margin: 0 16px 10px; box-shadow: 0 1px 4px rgba(0,0,0,0.05); overflow: hidden; }
.day-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.day-header .day-name { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.day-header .day-summary { font-size: 12px; color: #999; }
.day-header .arrow { width: 16px; height: 16px; color: #ccc; transition: transform .2s; flex-shrink: 0; }
.day-header .arrow.open { transform: rotate(180deg); }
.day-body { max-height: 0; overflow: hidden; transition: max-height .25s ease; }
.day-body.open { max-height: 400px; }
.day-body-inner { padding: 0 16px 14px; }
.slot-row { display: flex; align-items: center; padding: 10px 0; border-top: 1px solid #f5f5f5; }
.slot-row:first-child { border-top: none; }
.slot-info { flex: 1; min-width: 0; }
.slot-period { font-size: 11px; color: #1677ff; font-weight: 500; margin-bottom: 1px; }
.slot-time { font-size: 13px; color: #1a1a1a; }
.slot-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.slot-toggle { position: relative; width: 40px; height: 22px; border-radius: 11px; background: #e0e0e0; cursor: pointer; transition: background .2s; }
.slot-toggle.on { background: #4cd964; }
.slot-toggle::after { content: ''; position: absolute; top: 2px; left: 2px; width: 18px; height: 18px; border-radius: 50%; background: #fff; box-shadow: 0 1px 2px rgba(0,0,0,.2); transition: transform .2s; }
.slot-toggle.on::after { transform: translateX(18px); }
.slot-count { display: flex; align-items: center; gap: 4px; }
.count-btn { width: 26px; height: 26px; border-radius: 50%; border: 1px solid #e8e8e8; background: #fff; font-size: 15px; color: #666; cursor: pointer; display: flex; align-items: center; justify-content: center; line-height: 1; }
.count-btn:active { background: #f5f5f5; }
.count-val { font-size: 15px; font-weight: 700; color: #1677ff; min-width: 18px; text-align: center; }
.count-unit { font-size: 11px; color: #999; }
.slot-row.disabled .slot-time { color: #ccc; }
.slot-row.disabled .slot-period { color: #b8d4ff; }
.slot-row.disabled .count-val { color: #ccc; }
.slot-row.disabled .count-btn { border-color: #f0f0f0; color: #ccc; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">排班设置</span>
<button class="nav-right">保存</button>
</div>
<div class="scroll-content">
<!-- 开启营养咨询 -->
<div style="background:#fff;padding:14px 16px;display:flex;align-items:center;gap:10px;margin-bottom:10px;">
<span style="font-size:14px;color:#1a1a1a;font-weight:500;">开启营养咨询</span>
<div class="toggle on" onclick="this.classList.toggle('on');var t=this.nextElementSibling;t.textContent=this.classList.contains('on')?'已开启 — 员工可发起营养咨询':'已关闭';t.style.color=this.classList.contains('on')?'#4cd964':'#999';"></div>
<span style="font-size:12px;color:#4cd964;flex:1;">已开启 — 员工可发起营养咨询</span>
</div>
<!-- 标题 -->
<div style="padding:2px 16px 10px;display:flex;align-items:center;gap:6px;">
<span style="width:3px;height:14px;background:#1677ff;border-radius:2px;display:inline-block;"></span>
<span style="font-size:14px;font-weight:600;color:#1a1a1a;">每周排班设置</span>
</div>
<div id="cardList"></div>
<div style="height:20px;"></div>
</div>
</div>
<script>
var DAYS = ['周一','周二','周三','周四','周五','周六','周日'];
var SLOTS = [
{ period: '上午', time: '8:00 10:00' },
{ period: '上午', time: '10:00 12:00' },
{ period: '下午', time: '14:00 16:00' },
{ period: '下午', time: '16:00 18:00' }
];
var DATA = DAYS.map(function(_, i) {
var off = i >= 5;
return { slots: SLOTS.map(function(_, si) {
return { on: !off, n: off ? 0 : (si < 2 ? 5 : 4) };
})};
});
var arrowSvg = '<svg class="arrow" viewBox="0 0 16 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 6l4 4 4-4"/></svg>';
function getSummary(di) {
var d = DATA[di], cnt = 0;
d.slots.forEach(function(s) { if (s.on) cnt++; });
return cnt > 0 ? cnt + '个时段开诊' : '休息';
}
function render() {
var wrap = document.getElementById('cardList');
wrap.innerHTML = '';
DAYS.forEach(function(day, di) {
var card = document.createElement('div');
card.className = 'day-card';
card.innerHTML =
'<div class="day-header" onclick="toggle(' + di + ')">' +
'<div><span class="day-name">' + day + '</span> ' +
'<span class="day-summary">' + getSummary(di) + '</span></div>' +
arrowSvg +
'</div>' +
'<div class="day-body" id="body-' + di + '">' +
'<div class="day-body-inner">' + renderSlots(di) + '</div>' +
'</div>';
wrap.appendChild(card);
});
var first = document.getElementById('body-0');
if (first) { first.classList.add('open'); first.previousElementSibling.querySelector('.arrow').classList.add('open'); }
}
function renderSlots(di) {
var html = '';
DATA[di].slots.forEach(function(s, si) {
var dis = s.on ? '' : ' disabled';
var tCls = s.on ? 'slot-toggle on' : 'slot-toggle';
html += '<div class="slot-row' + dis + '">' +
'<div class="slot-info">' +
'<div class="slot-period">' + SLOTS[si].period + '</div>' +
'<div class="slot-time">' + SLOTS[si].time + '</div>' +
'</div>' +
'<div class="slot-right">' +
'<div class="' + tCls + '" onclick="toggleSlot(' + di + ',' + si + ')"></div>' +
'<div class="slot-count">' +
'<button class="count-btn" ' + (s.on ? '' : 'disabled ') + 'onclick="adj(' + di + ',' + si + ',-1)"></button>' +
'<span class="count-val">' + (s.on ? s.n : '—') + '</span>' +
'<button class="count-btn" ' + (s.on ? '' : 'disabled ') + 'onclick="adj(' + di + ',' + si + ',1)">+</button>' +
'<span class="count-unit">人</span>' +
'</div>' +
'</div></div>';
});
return html;
}
function toggle(di) {
var body = document.getElementById('body-' + di);
var arrow = body.previousElementSibling.querySelector('.arrow');
body.classList.toggle('open');
arrow.classList.toggle('open');
}
function toggleSlot(di, si) {
var s = DATA[di].slots[si];
s.on = !s.on;
if (s.on && s.n === 0) s.n = 3;
refreshCard(di);
}
function adj(di, si, delta) {
var s = DATA[di].slots[si];
if (!s.on) return;
s.n = Math.max(1, Math.min(20, s.n + delta));
refreshCard(di);
}
function refreshCard(di) {
var body = document.getElementById('body-' + di);
var wasOpen = body.classList.contains('open');
body.querySelector('.day-body-inner').innerHTML = renderSlots(di);
var header = body.previousElementSibling;
header.querySelector('.day-summary').textContent = getSummary(di);
if (wasOpen) body.classList.add('open');
}
render();
</script>
</body>
</html>
@@ -0,0 +1,143 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师 - 营养咨询统计 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">营养咨询统计</span>
</div>
<div class="scroll-content" style="padding:16px;">
<!-- 月度统计 -->
<div style="background:#fff;border-radius:12px;padding:20px;margin-bottom:16px;box-shadow:0 1px 6px rgba(0,0,0,0.06);">
<div style="display:flex;align-items:center;justify-content:center;gap:16px;margin-bottom:20px;">
<button onclick="prevMonth()" style="background:none;border:none;color:#1677ff;font-size:18px;cursor:pointer;padding:4px 8px;">
<svg width="8" height="14" viewBox="0 0 8 14" fill="none" stroke="currentColor" stroke-width="2"><path d="M7 1L1 7l6 6"/></svg>
</button>
<div style="font-size:17px;font-weight:600;color:#1a1a1a;min-width:120px;text-align:center;" id="current-month">2026年9月</div>
<button onclick="nextMonth()" style="background:none;border:none;color:#1677ff;font-size:18px;cursor:pointer;padding:4px 8px;">
<svg width="8" height="14" viewBox="0 0 8 14" fill="none" stroke="currentColor" stroke-width="2"><path d="M1 1l6 6-6 6"/></svg>
</button>
</div>
<!-- 概览(3列) -->
<div style="display:flex;gap:8px;margin-bottom:24px;">
<div style="flex:1;background:#e6f4ff;border-radius:10px;padding:14px 8px;text-align:center;">
<div style="font-size:20px;font-weight:700;color:#1677ff;">213</div>
<div style="font-size:11px;color:#666;margin-top:4px;">营养咨询</div>
</div>
<div style="flex:1;background:#f6ffed;border-radius:10px;padding:14px 8px;text-align:center;">
<div style="font-size:20px;font-weight:700;color:#52c41a;">48</div>
<div style="font-size:11px;color:#666;margin-top:4px;">营养方案</div>
</div>
<div style="flex:1;background:#fff7e6;border-radius:10px;padding:14px 8px;text-align:center;">
<div style="font-size:20px;font-weight:700;color:#fa8c16;">12</div>
<div style="font-size:11px;color:#666;margin-top:4px;">发布食谱</div>
</div>
</div>
<!-- 咨询主题分布(饼状图) -->
<div style="display:flex;align-items:center;gap:24px;margin-bottom:24px;">
<svg width="130" height="130" viewBox="0 0 100 100" style="flex-shrink:0;">
<circle cx="50" cy="50" r="40" fill="none" stroke="#1677ff" stroke-width="20"
stroke-dasharray="126 250" stroke-dashoffset="0" transform="rotate(-90 50 50)"/>
<circle cx="50" cy="50" r="40" fill="none" stroke="#52c41a" stroke-width="20"
stroke-dasharray="75 250" stroke-dashoffset="-126" transform="rotate(-90 50 50)"/>
<circle cx="50" cy="50" r="40" fill="none" stroke="#fa8c16" stroke-width="20"
stroke-dasharray="49 250" stroke-dashoffset="-201" transform="rotate(-90 50 50)"/>
<circle cx="50" cy="50" r="28" fill="#fff"/>
<text x="50" y="48" text-anchor="middle" font-size="18" font-weight="700" fill="#1a1a1a">213</text>
<text x="50" y="60" text-anchor="middle" font-size="10" fill="#999">总咨询</text>
</svg>
<div style="flex:1;">
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="width:12px;height:12px;background:#1677ff;border-radius:3px;flex-shrink:0;"></div>
<div style="flex:1;"><span style="font-size:13px;color:#666;">减脂控糖</span></div>
<span style="font-size:15px;font-weight:700;color:#1a1a1a;">107<span style="font-size:11px;color:#999;"> (50%)</span></span>
</div>
<div style="display:flex;align-items:center;gap:8px;margin-bottom:12px;">
<div style="width:12px;height:12px;background:#52c41a;border-radius:3px;flex-shrink:0;"></div>
<div style="flex:1;"><span style="font-size:13px;color:#666;">慢性病营养</span></div>
<span style="font-size:15px;font-weight:700;color:#1a1a1a;">64<span style="font-size:11px;color:#999;"> (30%)</span></span>
</div>
<div style="display:flex;align-items:center;gap:8px;">
<div style="width:12px;height:12px;background:#fa8c16;border-radius:3px;flex-shrink:0;"></div>
<div style="flex:1;"><span style="font-size:13px;color:#666;">其他</span></div>
<span style="font-size:15px;font-weight:700;color:#1a1a1a;">42<span style="font-size:11px;color:#999;"> (20%)</span></span>
</div>
</div>
</div>
<!-- 月度趋势折线图 -->
<div style="border-top:1px solid #f0f0f0;padding-top:20px;">
<div style="font-size:14px;font-weight:600;color:#1a1a1a;margin-bottom:16px;">月度趋势</div>
<svg width="100%" height="180" viewBox="0 0 340 180" style="overflow:visible;">
<line x1="0" y1="150" x2="340" y2="150" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="120" x2="340" y2="120" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="90" x2="340" y2="90" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="60" x2="340" y2="60" stroke="#f0f0f0" stroke-width="1"/>
<line x1="0" y1="30" x2="340" y2="30" stroke="#f0f0f0" stroke-width="1"/>
<polyline points="5,126 27,108 49,90 71,60 93,138 115,48 137,96 159,78 181,114 203,66 225,132 247,90 269,120 291,54 313,144 335,42"
fill="none" stroke="#1677ff" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="93" cy="138" r="3.5" fill="#1677ff"/>
<circle cx="159" cy="78" r="3.5" fill="#1677ff"/>
<circle cx="203" cy="66" r="6" fill="#1677ff" stroke="#fff" stroke-width="2.5"/>
<text x="93" y="168" text-anchor="middle" font-size="11" fill="#bbb">6</text>
<text x="159" y="168" text-anchor="middle" font-size="11" fill="#bbb">12</text>
<text x="203" y="168" text-anchor="middle" font-size="11" fill="#1677ff" font-weight="600"></text>
<text x="335" y="168" text-anchor="middle" font-size="11" fill="#bbb">30</text>
<text x="203" y="54" text-anchor="middle" font-size="12" fill="#1677ff" font-weight="600">15</text>
<text x="-5" y="153" text-anchor="end" font-size="10" fill="#bbb">0</text>
<text x="-5" y="123" text-anchor="end" font-size="10" fill="#bbb">5</text>
<text x="-5" y="93" text-anchor="end" font-size="10" fill="#bbb">10</text>
<text x="-5" y="63" text-anchor="end" font-size="10" fill="#bbb">15</text>
<text x="-5" y="33" text-anchor="end" font-size="10" fill="#bbb">20</text>
</svg>
</div>
</div>
<div style="height:20px;"></div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
function prevMonth() { alert('切换到上个月(演示)'); }
function nextMonth() { alert('切换到下个月(演示)'); }
</script>
</body>
</html>
@@ -0,0 +1,80 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 营养咨询聊天(已结束) | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">赵磊</span>
</div>
<!-- 咨询已结束提示条 -->
<div style="background:#fff7e6;padding:8px 16px;font-size:12px;color:#d46b08;flex-shrink:0;text-align:center;">本次营养咨询已结束,仅可查看历史记录</div>
<!-- 消息区(只读) -->
<div class="scroll-content" style="padding:12px 16px;">
<div style="text-align:center;margin:8px 0;"><span style="font-size:11px;color:#bbb;background:#ebebeb;padding:3px 10px;border-radius:10px;">昨天 08:30</span></div>
<!-- 员工消息 -->
<div style="display:flex;gap:8px;margin-bottom:14px;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ffe0e0,#ffb3b3);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">👨</div>
<div><div style="font-size:11px;color:#999;margin-bottom:4px;">赵磊</div>
<div style="background:#fff;border-radius:0 12px 12px 12px;padding:10px 14px;font-size:14px;color:#1a1a1a;max-width:220px;box-shadow:0 1px 4px rgba(0,0,0,0.06);line-height:1.5;">营养师您好,我最近体检尿酸偏高,日常饮食要注意什么?</div>
</div>
</div>
<!-- 营养师消息 -->
<div style="display:flex;gap:8px;margin-bottom:14px;flex-direction:row-reverse;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">🥗</div>
<div style="display:flex;flex-direction:column;align-items:flex-end;">
<div style="font-size:11px;color:#999;margin-bottom:4px;">李营养师(我)</div>
<div style="background:#1677ff;border-radius:12px 0 12px 12px;padding:10px 14px;font-size:14px;color:#fff;max-width:220px;line-height:1.5;">高尿酸人群建议限制高嘌呤食物(动物内脏、海鲜、浓肉汤),避免饮酒,多饮水,每日 2000ml 以上,控制体重。</div>
</div>
</div>
<div style="text-align:center;margin:8px 0;"><span style="font-size:11px;color:#bbb;background:#ebebeb;padding:3px 10px;border-radius:10px;">昨天 08:45</span></div>
<!-- 员工结束消息 -->
<div style="display:flex;gap:8px;margin-bottom:14px;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ffe0e0,#ffb3b3);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">👨</div>
<div><div style="font-size:11px;color:#999;margin-bottom:4px;">赵磊</div>
<div style="background:#fff;border-radius:0 12px 12px 12px;padding:10px 14px;font-size:14px;color:#1a1a1a;max-width:220px;box-shadow:0 1px 4px rgba(0,0,0,0.06);line-height:1.5;">谢谢营养师,方案很实用,我会坚持执行。</div>
</div>
</div>
<!-- 结束标记 -->
<div style="text-align:center;margin:16px 0;">
<span style="font-size:12px;color:#bbb;">— 咨询已结束 —</span>
</div>
<div style="height:8px;"></div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
</script>
</body>
</html>
@@ -0,0 +1,328 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 营养咨询聊天 | 健康CQ原型</title>
<style>
/* 公共重置与布局 */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
/* 导航栏 */
.nav-bar { height: 44px; display: flex; align-items: center; padding: 0 16px; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; position: relative; }
.back-btn { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.nav-right { margin-left: auto; color: #ff4d4f; font-size: 14px; cursor: pointer; background: none; border: none; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
/* 员工档案卡片 */
.bubble-record { max-width: 260px; border-radius: 0 12px 12px 12px; overflow: hidden; background: #fff; border: 1px solid #e8e8e8; box-shadow: 0 1px 4px rgba(0,0,0,0.06); cursor: pointer; }
.bubble-record__header { display: flex; align-items: center; gap: 8px; padding: 10px 12px; background: linear-gradient(135deg, #e8f4ff, #bae0ff); }
.bubble-record__avatar { width: 32px; height: 32px; border-radius: 50%; background: #fff; display: flex; align-items: center; justify-content: center; font-size: 16px; flex-shrink: 0; }
.bubble-record__name { font-size: 13px; font-weight: 600; color: #333; }
.bubble-record__meta { font-size: 11px; color: #666; }
.bubble-record__body { padding: 10px 12px; }
.bubble-record__title { font-size: 13px; font-weight: 600; color: #333; margin-bottom: 4px; }
.bubble-record__desc { font-size: 12px; color: #666; line-height: 1.5; }
.bubble-record__tags { display: flex; gap: 4px; flex-wrap: wrap; margin-top: 6px; }
.bubble-record__tag { font-size: 10px; padding: 2px 6px; border-radius: 4px; }
.bubble-record__tag--green { color: #52c41a; background: #f6ffed; }
.bubble-record__tag--orange { color: #d46b08; background: #fff7e6; }
/* 常用语分类与列表 */
.quick-cat { font-size: 12px; padding: 4px 12px; border-radius: 14px; background: #f5f5f5; color: #666; cursor: pointer; user-select: none; transition: all .2s; }
.quick-cat.active { background: #e6f4ff; color: #1677ff; font-weight: 600; }
.quick-item { font-size: 13px; color: #1a1a1a; padding: 8px 0; border-bottom: 1px solid #f0f0f0; cursor: pointer; }
.quick-item:last-child { border-bottom: none; }
.quick-item:active { color: #1677ff; }
/* 快捷操作栏 */
.action-bar { display: flex; gap: 8px; background: #fff; border-bottom: 1px solid #f0f0f0; padding: 8px 16px; flex-shrink: 0; }
.action-btn { flex: 1; display: flex; align-items: center; justify-content: center; gap: 6px; padding: 8px 0; border-radius: 8px; font-size: 13px; cursor: pointer; }
.action-btn--blue { background: #e6f4ff; color: #1677ff; }
.action-btn--green { background: #f6ffed; color: #52c41a; }
/* 底部弹层 */
.sheet-mask { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 300; align-items: flex-end; justify-content: center; }
.sheet-mask.active { display: flex; }
.sheet-panel { width: 100%; max-height: 80%; background: #fff; border-radius: 16px 16px 0 0; display: flex; flex-direction: column; overflow: hidden; }
.sheet-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 0.5px solid #f0f0f0; flex-shrink: 0; }
.sheet-header .s-cancel { font-size: 14px; color: #999; cursor: pointer; background: none; border: none; }
.sheet-header .s-title { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.sheet-header .s-save { font-size: 14px; color: #1677ff; font-weight: 600; cursor: pointer; background: none; border: none; }
.sheet-body { padding: 12px 16px 20px; overflow-y: auto; flex: 1; }
.sheet-body::-webkit-scrollbar { display: none; }
.form-item { margin-bottom: 14px; }
.form-item__label { font-size: 13px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; }
.form-input { width: 100%; border: 1px solid #e8e8e8; border-radius: 8px; padding: 10px 12px; font-size: 14px; outline: none; color: #1a1a1a; }
.form-input:focus { border-color: #1677ff; }
.ratio-row { display: flex; gap: 8px; }
.ratio-row .form-input { flex: 1; text-align: center; }
.tag-picker { display: flex; gap: 6px; flex-wrap: wrap; }
.tag-picker .tag-opt { font-size: 12px; padding: 5px 12px; border-radius: 14px; background: #f5f5f5; color: #666; cursor: pointer; }
.tag-picker .tag-opt.active { background: #e6f4ff; color: #1677ff; font-weight: 600; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<!-- [交互] 点击返回: ./index.html -->
<button class="back-btn" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">张小红</span>
<!-- [交互] 点击打开结束咨询弹窗 -->
<button class="nav-right" onclick="openModal('modal-end-confirm')">结束咨询</button>
</div>
<!-- 快捷操作栏 -->
<div class="action-bar">
<!-- [交互] 点击跳转至: ./employee-health.html 查看员工健康档案 -->
<div class="action-btn action-btn--blue" onclick="location.href='./employee-health.html'">📋 健康档案</div>
<!-- [交互] 点击打开制定营养方案弹层 -->
<div class="action-btn action-btn--green" onclick="openSheet('sheet-plan')">🎯 制定方案</div>
</div>
<!-- 消息区 -->
<div class="scroll-content" id="chat-scroll" style="padding:12px 16px;">
<!-- 时间标记 -->
<div style="text-align:center;margin:8px 0;"><span style="font-size:11px;color:#bbb;background:#ebebeb;padding:3px 10px;border-radius:10px;">10:20</span></div>
<!-- [交互] 员工营养档案卡片 - 点击查看员工营养详情 -->
<div style="display:flex;gap:8px;margin-bottom:14px;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ffe0e0,#ffb3b3);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">👩</div>
<div><div style="font-size:11px;color:#999;margin-bottom:4px;">张小红</div>
<div class="bubble-record" onclick="location.href='./employee-detail.html'">
<div class="bubble-record__header">
<div class="bubble-record__avatar">👩</div>
<div>
<div class="bubble-record__name">张小红 · 女 · 32岁</div>
<div class="bubble-record__meta">162cm · 67kg · BMI 25.6</div>
</div>
</div>
<div class="bubble-record__body">
<div class="bubble-record__title">减脂营养咨询</div>
<div class="bubble-record__desc">食堂饭菜偏油,想请教日常减脂怎么搭配饮食</div>
<div class="bubble-record__tags">
<span class="bubble-record__tag bubble-record__tag--green">目标:减脂 5kg</span>
</div>
</div>
</div>
</div>
</div>
<!-- 员工消息(左侧) -->
<div style="display:flex;gap:8px;margin-bottom:14px;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#ffe0e0,#ffb3b3);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">👩</div>
<div><div style="font-size:11px;color:#999;margin-bottom:4px;">张小红</div>
<div style="background:#fff;border-radius:0 12px 12px 12px;padding:10px 14px;font-size:14px;color:#1a1a1a;max-width:220px;box-shadow:0 1px 4px rgba(0,0,0,0.06);line-height:1.5;">营养师您好,我最近在减脂,但食堂的红烧肉、油炸类菜品偏多,不知道怎么吃才不会超标。</div>
</div>
</div>
<!-- 时间标记 -->
<div style="text-align:center;margin:8px 0;"><span style="font-size:11px;color:#bbb;background:#ebebeb;padding:3px 10px;border-radius:10px;">10:23</span></div>
<!-- 营养师消息(右侧) -->
<div style="display:flex;gap:8px;margin-bottom:14px;flex-direction:row-reverse;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">🥗</div>
<div style="display:flex;flex-direction:column;align-items:flex-end;">
<div style="font-size:11px;color:#999;margin-bottom:4px;">李营养师(我)</div>
<div style="background:#1677ff;border-radius:12px 0 12px 12px;padding:10px 14px;font-size:14px;color:#fff;max-width:220px;line-height:1.5;">您好,减脂期在食堂就餐建议:主菜优先选清蒸、白灼、凉拌类,肉类选去皮鸡胸、鱼虾;主食粗细搭配,每餐一拳主食、一掌蛋白质、两拳蔬菜。</div>
</div>
</div>
<!-- 营养师消息:推荐食谱卡片 -->
<div style="display:flex;gap:8px;margin-bottom:14px;flex-direction:row-reverse;">
<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">🥗</div>
<div style="display:flex;flex-direction:column;align-items:flex-end;">
<div style="font-size:11px;color:#999;margin-bottom:4px;">李营养师(我)</div>
<div style="background:#fff;border-radius:12px 0 12px 12px;padding:10px;max-width:220px;box-shadow:0 1px 4px rgba(0,0,0,0.08);cursor:pointer;" onclick="location.href='./plan-detail.html'">
<div style="font-size:12px;color:#999;margin-bottom:6px;">为您推荐个性化营养方案</div>
<div style="font-size:14px;font-weight:600;color:#1a1a1a;">减脂期一周饮食方案</div>
<div style="font-size:12px;color:#666;margin-top:4px;line-height:1.5;">每日热量 1400 kcal · 蛋白质 25% · 脂肪 20% · 碳水 55%</div>
<div style="display:flex;align-items:center;justify-content:space-between;margin-top:8px;padding-top:8px;border-top:1px solid #f0f0f0;">
<span style="font-size:11px;color:#52c41a;">● 已生成</span>
<span style="font-size:12px;color:#1677ff;">查看详情 </span>
</div>
</div>
</div>
</div>
<div style="height:8px;"></div>
</div>
<!-- 常用语面板 -->
<div id="quick-panel" style="display:none;background:#fff;border-top:1px solid #f0f0f0;padding:10px 16px;flex-shrink:0;max-height:200px;overflow-y:auto;">
<div style="display:flex;gap:6px;margin-bottom:10px;">
<span class="quick-cat active" data-cat="all" onclick="filterQuick(this)">全部</span>
<span class="quick-cat" data-cat="greet" onclick="filterQuick(this)">问候语</span>
<span class="quick-cat" data-cat="ask" onclick="filterQuick(this)">问询</span>
<span class="quick-cat" data-cat="advice" onclick="filterQuick(this)">建议</span>
<span class="quick-cat" data-cat="end" onclick="filterQuick(this)">结束语</span>
</div>
<div id="quick-list">
<div class="quick-item" data-cat="greet" onclick="useQuick(this)">您好,我是您的专属营养师</div>
<div class="quick-item" data-cat="greet" onclick="useQuick(this)">您好,请描述您的饮食与健康目标</div>
<div class="quick-item" data-cat="ask" onclick="useQuick(this)">请问您目前的身高体重是多少?</div>
<div class="quick-item" data-cat="ask" onclick="useQuick(this)">是否有高血脂、糖尿病等慢性病史?</div>
<div class="quick-item" data-cat="ask" onclick="useQuick(this)">平时主要在食堂就餐还是自带餐?</div>
<div class="quick-item" data-cat="advice" onclick="useQuick(this)">建议主食粗细搭配,每餐一拳量</div>
<div class="quick-item" data-cat="advice" onclick="useQuick(this)">优先选择清蒸、白灼类菜品</div>
<div class="quick-item" data-cat="advice" onclick="useQuick(this)">控制油脂摄入,每日不超过 25g</div>
<div class="quick-item" data-cat="end" onclick="useQuick(this)">如有不适请及时调整并反馈</div>
<div class="quick-item" data-cat="end" onclick="useQuick(this)">祝您健康,欢迎随时咨询!</div>
</div>
</div>
<!-- 输入区 -->
<div style="background:#fff;border-top:1px solid #f0f0f0;padding:8px 12px 14px;flex-shrink:0;">
<div style="display:flex;align-items:center;gap:6px;">
<button onclick="toggleQuick()" style="width:34px;height:34px;border-radius:50%;background:#f5f5f5;border:none;font-size:16px;cursor:pointer;flex-shrink:0;"></button>
<button id="voice-btn" onclick="toggleVoice()" style="width:34px;height:34px;border-radius:50%;background:#f5f5f5;border:none;font-size:16px;cursor:pointer;flex-shrink:0;">🎤</button>
<input id="chat-input" type="text" placeholder="输入营养建议..." style="flex:1;background:#f5f5f5;border:none;border-radius:20px;padding:8px 14px;font-size:14px;outline:none;color:#1a1a1a;" />
<button id="voice-record-btn" style="display:none;flex:1;height:36px;background:#f5f5f5;border:1.5px solid #d9d9d9;border-radius:20px;font-size:13px;color:#555;cursor:pointer;text-align:center;align-items:center;justify-content:center;letter-spacing:1px;">按住说话</button>
<button onclick="sendMsg()" style="width:34px;height:34px;border-radius:50%;background:#1677ff;border:none;font-size:16px;cursor:pointer;flex-shrink:0;color:#fff;display:flex;align-items:center;justify-content:center;"></button>
</div>
</div>
<!-- 结束咨询确认弹窗 -->
<div id="modal-end-confirm" class="modal-center">
<div class="modal-box">
<div class="modal-title">结束咨询</div>
<div class="modal-body">确认结束与张小红的营养咨询?结束后将无法继续发送消息。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-end-confirm')">取消</button>
<button onclick="closeModal('modal-end-confirm');location.href='./index.html'">确认结束</button>
</div>
</div>
</div>
<!-- 制定营养方案底部弹层 -->
<div id="sheet-plan" class="sheet-mask" onclick="if(event.target===this)closeSheet('sheet-plan')">
<div class="sheet-panel" onclick="event.stopPropagation()">
<div class="sheet-header">
<button class="s-cancel" onclick="closeSheet('sheet-plan')">取消</button>
<span class="s-title">为张小红制定营养方案</span>
<button class="s-save" onclick="savePlan()">保存</button>
</div>
<div class="sheet-body">
<div class="form-item">
<div class="form-item__label">目标热量(kcal/日)</div>
<input class="form-input" type="text" value="1400" />
</div>
<div class="form-item">
<div class="form-item__label">三大营养素占比(%</div>
<div class="ratio-row">
<input class="form-input" type="text" value="25" placeholder="蛋白" />
<input class="form-input" type="text" value="20" placeholder="脂肪" />
<input class="form-input" type="text" value="55" placeholder="碳水" />
</div>
</div>
<div class="form-item">
<div class="form-item__label">饮食禁忌</div>
<div class="tag-picker">
<span class="tag-opt active" onclick="toggleTag(this)">高糖</span>
<span class="tag-opt active" onclick="toggleTag(this)">高脂</span>
<span class="tag-opt" onclick="toggleTag(this)">高盐</span>
<span class="tag-opt active" onclick="toggleTag(this)">高嘌呤</span>
<span class="tag-opt" onclick="toggleTag(this)">乳糖</span>
</div>
</div>
<div class="form-item">
<div class="form-item__label">目标描述</div>
<input class="form-input" type="text" value="减脂 5kg,控制尿酸" />
</div>
</div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
/* 切换常用语面板 */
function toggleQuick() {
var p = document.getElementById('quick-panel');
p.style.display = p.style.display === 'none' ? 'block' : 'none';
}
/* 语音模式状态 */
var isVoiceMode = false;
function toggleVoice() {
isVoiceMode = !isVoiceMode;
var input = document.getElementById('chat-input');
var voiceBtn = document.getElementById('voice-btn');
var recordBtn = document.getElementById('voice-record-btn');
if (isVoiceMode) {
input.style.display = 'none';
recordBtn.style.display = 'flex';
voiceBtn.textContent = '⌨️';
voiceBtn.style.background = '#e6f4ff';
} else {
input.style.display = '';
recordBtn.style.display = 'none';
voiceBtn.textContent = '🎤';
voiceBtn.style.background = '#f5f5f5';
}
}
/* 使用常用语填充输入框 */
function useQuick(el) {
document.getElementById('chat-input').value = el.textContent;
document.getElementById('quick-panel').style.display = 'none';
}
/* 常用语分类筛选 */
function filterQuick(tab) {
tab.parentElement.querySelectorAll('.quick-cat').forEach(function(t) { t.classList.remove('active'); });
tab.classList.add('active');
var cat = tab.dataset.cat;
document.querySelectorAll('#quick-list .quick-item').forEach(function(item) {
item.style.display = (cat === 'all' || item.dataset.cat === cat) ? '' : 'none';
});
}
/* 发送消息,在聊天区追加一条营养师消息气泡 */
function sendMsg() {
var input = document.getElementById('chat-input');
var text = input.value.trim();
if (!text) return;
var scroll = document.getElementById('chat-scroll');
var bubble = document.createElement('div');
bubble.style.cssText = 'display:flex;gap:8px;margin-bottom:14px;flex-direction:row-reverse;';
bubble.innerHTML = '<div style="width:36px;height:36px;border-radius:50%;background:linear-gradient(135deg,#e8f4ff,#bdd7ff);display:flex;align-items:center;justify-content:center;font-size:16px;flex-shrink:0;">🥗</div><div style="display:flex;flex-direction:column;align-items:flex-end;"><div style="font-size:11px;color:#999;margin-bottom:4px;">李营养师(我)</div><div style="background:#1677ff;border-radius:12px 0 12px 12px;padding:10px 14px;font-size:14px;color:#fff;max-width:220px;line-height:1.5;">' + text + '</div></div>';
scroll.insertBefore(bubble, scroll.lastElementChild);
input.value = '';
scroll.scrollTop = scroll.scrollHeight;
}
/* 打开底部弹层 */
function openSheet(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
/* 关闭底部弹层 */
function closeSheet(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
/* 禁忌标签选择 */
function toggleTag(el) { el.classList.toggle('active'); }
/* 保存方案并关闭弹层 */
function savePlan() {
closeSheet('sheet-plan');
alert('营养方案已保存,系统将自动生成一周专属食谱并推送至员工端(原型演示)');
}
</script>
</body>
</html>
@@ -0,0 +1,249 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 员工营养详情 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 员工信息头 */
.emp-header { background: linear-gradient(135deg,#1677ff,#0958d9); padding: 16px 20px; color: #fff; }
.emp-header__name { font-size: 18px; font-weight: 700; }
.emp-header__meta { font-size: 12px; color: rgba(255,255,255,0.85); margin-top: 4px; }
.emp-header__tags { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.emp-header__tag { font-size: 11px; padding: 3px 10px; border-radius: 12px; background: rgba(255,255,255,0.2); }
/* 区块卡片 */
.card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.card__title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 10px; display: flex; align-items: center; justify-content: space-between; }
.card__title-extra { font-size: 12px; color: #1677ff; font-weight: 400; cursor: pointer; }
/* 达标概览 */
.overview-row { display: flex; }
.overview-item { flex: 1; text-align: center; }
.overview-item + .overview-item { border-left: 1px solid #f0f0f0; }
.overview-item__val { font-size: 18px; font-weight: 700; }
.overview-item__val--good { color: #52c41a; }
.overview-item__val--bad { color: #ff4d4f; }
.overview-item__label { font-size: 11px; color: #999; margin-top: 2px; }
/* 膳食宝塔 */
.pyramid { display: flex; flex-direction: column; gap: 6px; }
.pyramid-row { display: flex; align-items: center; gap: 8px; }
.pyramid-row__label { width: 56px; font-size: 12px; color: #666; flex-shrink: 0; }
.pyramid-row__bar { flex: 1; height: 10px; background: #f0f0f0; border-radius: 5px; overflow: hidden; }
.pyramid-row__fill { height: 100%; border-radius: 5px; }
.pyramid-row__val { width: 40px; font-size: 11px; color: #999; text-align: right; flex-shrink: 0; }
/* 摄入明细 */
.meal-row { display: flex; align-items: center; justify-content: space-between; padding: 10px 0; border-bottom: 1px solid #f5f5f5; }
.meal-row:last-child { border-bottom: none; }
.meal-row__left { display: flex; align-items: center; gap: 8px; }
.meal-row__icon { font-size: 18px; }
.meal-row__name { font-size: 14px; color: #1a1a1a; font-weight: 500; }
.meal-row__kcal { font-size: 14px; font-weight: 700; color: #fa8c16; }
.meal-row__kcal span { font-size: 11px; font-weight: 400; color: #999; }
/* 营养方案 */
.plan-box { background: #f6ffed; border: 1px solid #b7eb8f; border-radius: 10px; padding: 12px; }
.plan-box__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.plan-box__name { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.plan-box__status { font-size: 11px; color: #52c41a; font-weight: 600; }
.plan-box__row { display: flex; justify-content: space-between; font-size: 12px; color: #666; padding: 3px 0; }
.plan-box__row .val { color: #333; font-weight: 600; }
/* 方案编辑表单 */
.plan-form { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.form-item { margin-bottom: 14px; }
.form-item__label { font-size: 13px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; }
.form-input { width: 100%; border: 1px solid #e8e8e8; border-radius: 8px; padding: 10px 12px; font-size: 14px; outline: none; color: #1a1a1a; }
.form-input:focus { border-color: #1677ff; }
.ratio-row { display: flex; gap: 8px; }
.ratio-row .form-input { flex: 1; text-align: center; }
.tag-picker { display: flex; gap: 6px; flex-wrap: wrap; }
.tag-picker .tag-opt { font-size: 12px; padding: 5px 12px; border-radius: 14px; background: #f5f5f5; color: #666; cursor: pointer; }
.tag-picker .tag-opt.active { background: #e6f4ff; color: #1677ff; font-weight: 600; }
.btn-primary { width: 100%; padding: 12px; background: #1677ff; color: #fff; border: none; border-radius: 10px; font-size: 15px; font-weight: 600; cursor: pointer; }
.btn-ghost { width: 100%; padding: 12px; background: #fff; color: #1677ff; border: 1px solid #1677ff; border-radius: 10px; font-size: 15px; font-weight: 600; cursor: pointer; }
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./employee-list.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">员工营养详情</span>
</div>
<div class="scroll-content">
<!-- 员工信息头 -->
<div class="emp-header">
<div style="display:flex;justify-content:space-between;align-items:flex-start;">
<div>
<div class="emp-header__name">张小红</div>
<div class="emp-header__meta">女 · 32岁 · 公司机关 · 办公室 · 162cm · 67.2kg · BMI 25.6</div>
</div>
<!-- [交互] 点击跳转至: ./employee-health.html 查看员工健康档案 -->
<button onclick="location.href='./employee-health.html'" style="display:flex;align-items:center;gap:4px;background:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4);border-radius:16px;padding:6px 12px;color:#fff;font-size:12px;cursor:pointer;flex-shrink:0;">📋 健康档案</button>
</div>
<div class="emp-header__tags">
<span class="emp-header__tag">减脂需求</span>
<span class="emp-header__tag">轻体力活动</span>
</div>
</div>
<!-- 营养达标概览 -->
<div class="card">
<div class="card__title">营养达标概览</div>
<div class="overview-row">
<div class="overview-item"><div class="overview-item__val overview-item__val--bad">68%</div><div class="overview-item__label">综合达标率</div></div>
<div class="overview-item"><div class="overview-item__val">22</div><div class="overview-item__label">本月用餐天数</div></div>
<div class="overview-item"><div class="overview-item__val">1890</div><div class="overview-item__label">日均摄入(kcal)</div></div>
</div>
</div>
<!-- 膳食宝塔评估 -->
<div class="card">
<div class="card__title">膳食宝塔评估</div>
<div class="pyramid">
<div class="pyramid-row"><span class="pyramid-row__label">谷薯类</span><div class="pyramid-row__bar"><div class="pyramid-row__fill" style="width:82%;background:#52c41a;"></div></div><span class="pyramid-row__val">82%</span></div>
<div class="pyramid-row"><span class="pyramid-row__label">蔬菜水果</span><div class="pyramid-row__bar"><div class="pyramid-row__fill" style="width:45%;background:#fa8c16;"></div></div><span class="pyramid-row__val">45%</span></div>
<div class="pyramid-row"><span class="pyramid-row__label">畜禽鱼蛋</span><div class="pyramid-row__bar"><div class="pyramid-row__fill" style="width:110%;background:#ff4d4f;"></div></div><span class="pyramid-row__val">110%</span></div>
<div class="pyramid-row"><span class="pyramid-row__label">奶豆坚果</span><div class="pyramid-row__bar"><div class="pyramid-row__fill" style="width:38%;background:#fa8c16;"></div></div><span class="pyramid-row__val">38%</span></div>
<div class="pyramid-row"><span class="pyramid-row__label">油盐</span><div class="pyramid-row__bar"><div class="pyramid-row__fill" style="width:135%;background:#ff4d4f;"></div></div><span class="pyramid-row__val">135%</span></div>
</div>
</div>
<!-- 今日摄入明细 -->
<div class="card">
<div class="card__title">今日摄入明细<span class="card__title-extra" onclick="location.href='./employee-diet-history.html'">查看历史 </span></div>
<div class="meal-row"><div class="meal-row__left"><span class="meal-row__icon">🥣</span><span class="meal-row__name">早餐</span></div><div class="meal-row__kcal">486 <span>kcal</span></div></div>
<div class="meal-row"><div class="meal-row__left"><span class="meal-row__icon">🍱</span><span class="meal-row__name">午餐</span></div><div class="meal-row__kcal">720 <span>kcal</span></div></div>
<div class="meal-row"><div class="meal-row__left"><span class="meal-row__icon">🍎</span><span class="meal-row__name">加餐</span></div><div class="meal-row__kcal">185 <span>kcal</span></div></div>
<div class="meal-row"><div class="meal-row__left"><span class="meal-row__icon">🍽️</span><span class="meal-row__name">晚餐</span></div><div class="meal-row__kcal">560 <span>kcal</span></div></div>
</div>
<!-- 营养方案 -->
<div class="card">
<div class="card__title">营养方案</div>
<div class="plan-box" id="plan-box">
<div class="plan-box__head">
<span class="plan-box__name">减脂期一周饮食方案</span>
<span class="plan-box__status">执行中</span>
</div>
<div class="plan-box__row"><span>目标热量</span><span class="val">1400 kcal/日</span></div>
<div class="plan-box__row"><span>蛋白质 : 脂肪 : 碳水</span><span class="val">25% : 20% : 55%</span></div>
<div class="plan-box__row"><span>饮食禁忌</span><span class="val">高糖 · 高脂</span></div>
<div class="plan-box__row"><span>执行进度</span><span class="val">第 3 天 / 7 天</span></div>
</div>
<div style="display:flex;gap:10px;margin-top:12px;">
<!-- [交互] 点击跳转至: ./plan-detail.html 查看方案详情 -->
<button onclick="location.href='./plan-detail.html'" style="flex:1;padding:12px;background:#fff;color:#1677ff;border:1px solid #1677ff;border-radius:10px;font-size:15px;font-weight:600;cursor:pointer;">查看详情</button>
<!-- [交互] 点击展开方案编辑表单 -->
<button onclick="togglePlanForm()" style="flex:1;padding:12px;background:#1677ff;color:#fff;border:none;border-radius:10px;font-size:15px;font-weight:600;cursor:pointer;">调整方案</button>
</div>
</div>
<!-- 方案编辑表单 -->
<div class="plan-form" id="plan-form" style="display:none;">
<div class="form-item">
<div class="form-item__label">目标热量(kcal/日)</div>
<input class="form-input" type="text" value="1400" />
</div>
<div class="form-item">
<div class="form-item__label">三大营养素占比(%</div>
<div class="ratio-row">
<input class="form-input" type="text" value="25" placeholder="蛋白" />
<input class="form-input" type="text" value="20" placeholder="脂肪" />
<input class="form-input" type="text" value="55" placeholder="碳水" />
</div>
</div>
<div class="form-item">
<div class="form-item__label">饮食禁忌</div>
<div class="tag-picker">
<span class="tag-opt active" onclick="toggleTag(this)">高糖</span>
<span class="tag-opt active" onclick="toggleTag(this)">高脂</span>
<span class="tag-opt" onclick="toggleTag(this)">高盐</span>
<span class="tag-opt" onclick="toggleTag(this)">高嘌呤</span>
<span class="tag-opt" onclick="toggleTag(this)">乳糖</span>
</div>
</div>
<div class="form-item">
<div class="form-item__label">目标描述</div>
<input class="form-input" type="text" value="减脂 5kg,控制体脂率" />
</div>
<!-- [交互] 点击保存方案 -->
<button class="btn-primary" onclick="savePlan()">保存方案</button>
</div>
<div style="height:16px;"></div>
</div>
<!-- 保存成功弹窗 -->
<div id="modal-saved" class="modal-center">
<div class="modal-box">
<div class="modal-title">保存成功</div>
<div class="modal-body">营养方案已保存,系统将自动生成一周专属食谱并推送至员工端小程序。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-saved')">知道了</button>
</div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* 展开/收起方案编辑表单 */
function togglePlanForm() {
var form = document.getElementById('plan-form');
var isHidden = form.style.display === 'none';
form.style.display = isHidden ? 'block' : 'none';
if (isHidden) {
/* 展开后自动滚动到表单位置,避免表单在视口外用户看不到 */
setTimeout(function() {
form.scrollIntoView({ behavior: 'smooth', block: 'start' });
}, 50);
}
}
/* 禁忌标签选择 */
function toggleTag(el) {
el.classList.toggle('active');
}
/* 保存方案 */
function savePlan() {
document.getElementById('plan-form').style.display = 'none';
openModal('modal-saved');
}
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
</script>
</body>
</html>
@@ -0,0 +1,284 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 员工饮食记录 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 员工信息 */
.emp-info { background: linear-gradient(135deg,#1677ff,#0958d9); padding: 14px 20px; color: #fff; display: flex; align-items: center; gap: 12px; }
.emp-info__avatar { width: 42px; height: 42px; border-radius: 50%; background: rgba(255,255,255,0.25); border: 2px solid rgba(255,255,255,0.4); display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.emp-info__name { font-size: 16px; font-weight: 700; }
.emp-info__meta { font-size: 12px; color: rgba(255,255,255,0.85); margin-top: 2px; }
/* 日期导航 */
.date-nav { display: flex; align-items: center; justify-content: center; gap: 8px; padding: 10px 16px; background: #fff; border-bottom: 1px solid #f0f0f0; position: relative; flex-shrink: 0; }
.date-nav__arrow { width: 32px; height: 32px; border-radius: 50%; background: #f5f5f5; display: flex; align-items: center; justify-content: center; cursor: pointer; border: none; color: #666; font-size: 16px; flex-shrink: 0; }
.date-nav__arrow:active { background: #e6f4ff; }
.date-nav__text { font-size: 15px; font-weight: 600; color: #1a1a1a; min-width: 110px; text-align: center; }
.date-nav__cal { width: 28px; height: 28px; border-radius: 6px; background: none; display: flex; align-items: center; justify-content: center; cursor: pointer; border: none; font-size: 16px; flex-shrink: 0; color: #1677ff; }
/* 日历面板 */
.cal-panel { display: none; position: absolute; top: 42px; left: 16px; right: 16px; background: #fff; border-radius: 14px; box-shadow: 0 8px 30px rgba(0,0,0,0.15); z-index: 100; padding: 16px; }
.cal-panel.active { display: block; }
.cal-panel__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.cal-panel__month { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.cal-panel__nav { width: 28px; height: 28px; border-radius: 50%; border: none; background: #f5f5f5; cursor: pointer; font-size: 14px; color: #666; display: flex; align-items: center; justify-content: center; }
.cal-panel__weekdays { display: flex; margin-bottom: 6px; }
.cal-panel__weekday { flex: 1; text-align: center; font-size: 11px; color: #999; padding: 4px 0; }
.cal-panel__grid { display: flex; flex-wrap: wrap; }
.cal-panel__day { width: calc(100% / 7); text-align: center; padding: 8px 0; font-size: 13px; color: #333; cursor: pointer; border-radius: 8px; }
.cal-panel__day--other { color: #ddd; }
.cal-panel__day:hover { background: #f5f5f5; }
.cal-panel__day--today { font-weight: 700; color: #1677ff; }
.cal-panel__day--selected { background: #1677ff; color: #fff; font-weight: 700; }
/* 摄入汇总 */
.summary-card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.summary-card__title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 10px; }
.summary-row { display: flex; }
.summary-item { flex: 1; text-align: center; }
.summary-item + .summary-item { border-left: 1px solid #f0f0f0; }
.summary-item__val { font-size: 18px; font-weight: 700; }
.summary-item__val--over { color: #ff4d4f; }
.summary-item__val--ok { color: #52c41a; }
.summary-item__label { font-size: 11px; color: #999; margin-top: 2px; }
/* 三餐明细 */
.section-title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin: 14px 12px 6px; }
.meal-card { background: #fff; border-radius: 12px; margin: 8px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.meal-card__head { display: flex; align-items: center; margin-bottom: 8px; }
.meal-card__name { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.meal-card__time { font-size: 12px; color: #999; margin-left: 8px; }
.meal-card__kcal { margin-left: auto; font-size: 15px; font-weight: 700; color: #fa8c16; }
.meal-card__kcal span { font-size: 11px; font-weight: 400; color: #999; }
.meal-card__foods { display: flex; flex-wrap: wrap; gap: 6px; }
.food-tag { font-size: 12px; padding: 4px 10px; border-radius: 12px; background: #f0f6ff; color: #1677ff; }
.meal-card__source { margin-top: 8px; font-size: 11px; color: #999; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 600; }
.tag-blue { background: #e6f4ff; color: #1677ff; }
.tag-purple { background: #f9f0ff; color: #722ed1; }
/* 空状态 */
.empty-state { text-align: center; padding: 40px 0; color: #bbb; font-size: 13px; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./employee-detail.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">饮食记录</span>
</div>
<!-- 员工信息 -->
<div class="emp-info">
<div class="emp-info__avatar">👩</div>
<div>
<div class="emp-info__name">张小红</div>
<div class="emp-info__meta">女 · 32岁 · 公司机关 · 办公室</div>
</div>
</div>
<!-- 日期导航 -->
<div class="date-nav">
<button class="date-nav__arrow" onclick="changeDate(-1)"></button>
<button class="date-nav__cal" onclick="toggleCalPanel()">📅</button>
<span class="date-nav__text" id="dateText">2026-06-22</span>
<button class="date-nav__arrow" onclick="changeDate(1)"></button>
<!-- 日历选择面板 -->
<div class="cal-panel" id="calPanel">
<div class="cal-panel__head">
<button class="cal-panel__nav" onclick="calPrevMonth(event)"></button>
<span class="cal-panel__month" id="calMonthLabel">2026年6月</span>
<button class="cal-panel__nav" onclick="calNextMonth(event)"></button>
</div>
<div class="cal-panel__weekdays">
<div class="cal-panel__weekday"></div><div class="cal-panel__weekday"></div><div class="cal-panel__weekday"></div><div class="cal-panel__weekday"></div><div class="cal-panel__weekday"></div><div class="cal-panel__weekday"></div><div class="cal-panel__weekday"></div>
</div>
<div class="cal-panel__grid" id="calGrid"></div>
</div>
</div>
<div class="scroll-content">
<!-- 摄入汇总 -->
<div class="summary-card" id="summary-card">
<div class="summary-card__title">每日摄入汇总</div>
<div class="summary-row" id="summary-row"></div>
</div>
<!-- 当日三餐明细 -->
<div class="section-title">当日三餐明细</div>
<div id="meal-list"></div>
<div style="height:16px;"></div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* ===== 饮食记录历史数据 ===== */
var DIET_HISTORY = {
'2026-06-22': {
target: 1400,
meals: [
{ icon: '🥣', name: '早餐', time: '07:30', kcal: 486, source: '智记', cls: 'tag-blue', foods: ['全麦面包 80g', '水煮蛋 60g', '牛奶 250ml'] },
{ icon: '🍱', name: '午餐', time: '12:15', kcal: 720, source: '智记', cls: 'tag-blue', foods: ['清蒸鲈鱼 150g', '杂粮饭 200g', '蒜蓉西兰花 150g'] },
{ icon: '🍎', name: '加餐', time: '15:40', kcal: 185, source: '自记', cls: 'tag-purple', foods: ['苹果 1个', '坚果 30g'] },
{ icon: '🍽️', name: '晚餐', time: '18:30', kcal: 560, source: '智记', cls: 'tag-blue', foods: ['香煎鸡胸 120g', '蔬菜沙拉 200g', '小米粥 200g'] }
]
},
'2026-06-21': {
target: 1400,
meals: [
{ icon: '🥣', name: '早餐', time: '07:42', kcal: 450, source: '智记', cls: 'tag-blue', foods: ['燕麦牛奶 300ml', '水煮蛋 60g'] },
{ icon: '🍱', name: '午餐', time: '12:08', kcal: 680, source: '智记', cls: 'tag-blue', foods: ['白灼虾 150g', '糙米饭 200g', '清炒时蔬 150g'] },
{ icon: '🍎', name: '加餐', time: '15:30', kcal: 120, source: '自记', cls: 'tag-purple', foods: ['酸奶 1杯'] },
{ icon: '🍽️', name: '晚餐', time: '18:45', kcal: 520, source: '智记', cls: 'tag-blue', foods: ['蔬菜豆腐汤 300g', '杂粮馒头 100g'] }
]
},
'2026-06-20': {
target: 1400,
meals: [
{ icon: '🥣', name: '早餐', time: '07:35', kcal: 470, source: '智记', cls: 'tag-blue', foods: ['水煮蛋 60g', '豆浆 250ml', '蒸红薯 100g'] },
{ icon: '🍱', name: '午餐', time: '12:20', kcal: 660, source: '智记', cls: 'tag-blue', foods: ['卤牛肉 100g', '荞麦面 200g', '凉拌黄瓜 150g'] },
{ icon: '🍽️', name: '晚餐', time: '18:20', kcal: 540, source: '智记', cls: 'tag-blue', foods: ['清炒时蔬 200g', '玉米 150g', '菌菇汤 200g'] }
]
},
'2026-06-19': {
target: 1400,
meals: [
{ icon: '🥣', name: '早餐', time: '07:50', kcal: 430, source: '智记', cls: 'tag-blue', foods: ['杂粮粥 300g', '水煮蛋 60g'] },
{ icon: '🍱', name: '午餐', time: '12:10', kcal: 700, source: '智记', cls: 'tag-blue', foods: ['香煎鸡胸 150g', '藜麦饭 150g', '西兰花 150g'] },
{ icon: '🍎', name: '加餐', time: '16:00', kcal: 150, source: '自记', cls: 'tag-purple', foods: ['虾仁沙拉 200g'] },
{ icon: '🍽️', name: '晚餐', time: '18:40', kcal: 480, source: '智记', cls: 'tag-blue', foods: ['蔬菜沙拉 200g', '全麦面包 50g'] }
]
}
};
var currentDate = new Date(2026, 5, 22);
var calViewYear = currentDate.getFullYear();
var calViewMonth = currentDate.getMonth();
/* 计算某天总摄入 */
function dayTotal(data) {
return data.meals.reduce(function(s, m) { return s + m.kcal; }, 0);
}
/* 格式化日期为 YYYY-MM-DD */
function fmtDate(d) {
var y = d.getFullYear();
var m = String(d.getMonth() + 1).padStart(2, '0');
var day = String(d.getDate()).padStart(2, '0');
return y + '-' + m + '-' + day;
}
/* 渲染当前日期的饮食记录 */
function render() {
var key = fmtDate(currentDate);
document.getElementById('dateText').textContent = key;
var data = DIET_HISTORY[key];
if (!data) {
document.getElementById('summary-card').style.display = 'none';
document.getElementById('meal-list').innerHTML = '<div class="empty-state">当日暂无饮食记录</div>';
return;
}
document.getElementById('summary-card').style.display = 'block';
var total = dayTotal(data);
var diff = total - data.target;
var diffText = diff > 0 ? '+' + diff : diff;
var diffCls = diff > 0 ? 'summary-item__val--over' : 'summary-item__val--ok';
document.getElementById('summary-row').innerHTML =
'<div class="summary-item"><div class="summary-item__val" style="color:#1677ff;">' + total + '</div><div class="summary-item__label">总摄入 kcal</div></div>' +
'<div class="summary-item"><div class="summary-item__val" style="color:#333;">' + data.target + '</div><div class="summary-item__label">目标 kcal</div></div>' +
'<div class="summary-item"><div class="summary-item__val ' + diffCls + '">' + diffText + '</div><div class="summary-item__label">与目标差值</div></div>';
var mealsHtml = data.meals.map(function(m) {
var foodsHtml = m.foods.map(function(f) {
return '<span class="food-tag">' + f + '</span>';
}).join('');
return '<div class="meal-card">' +
'<div class="meal-card__head"><span class="meal-card__name">' + m.icon + ' ' + m.name + '</span><span class="meal-card__time">' + m.time + '</span><span class="meal-card__kcal">' + m.kcal + ' <span>kcal</span></span></div>' +
'<div class="meal-card__foods">' + foodsHtml + '</div>' +
'<div class="meal-card__source"><span class="tag ' + m.cls + '">' + m.source + '</span></div>' +
'</div>';
}).join('');
document.getElementById('meal-list').innerHTML = mealsHtml;
}
/* 切换日期 */
function changeDate(delta) {
currentDate.setDate(currentDate.getDate() + delta);
calViewYear = currentDate.getFullYear();
calViewMonth = currentDate.getMonth();
render();
}
/* 日历面板 */
function toggleCalPanel() {
var panel = document.getElementById('calPanel');
if (panel.classList.contains('active')) { panel.classList.remove('active'); return; }
calViewYear = currentDate.getFullYear();
calViewMonth = currentDate.getMonth();
renderCal();
panel.classList.add('active');
}
function calPrevMonth(e) { e.stopPropagation(); calViewMonth--; if (calViewMonth < 0) { calViewMonth = 11; calViewYear--; } renderCal(); }
function calNextMonth(e) { e.stopPropagation(); calViewMonth++; if (calViewMonth > 11) { calViewMonth = 0; calViewYear++; } renderCal(); }
function renderCal() {
document.getElementById('calMonthLabel').textContent = calViewYear + '年' + (calViewMonth + 1) + '月';
var firstDay = new Date(calViewYear, calViewMonth, 1).getDay();
var daysInMonth = new Date(calViewYear, calViewMonth + 1, 0).getDate();
var today = new Date(2026, 5, 22);
var html = '';
for (var i = 0; i < firstDay; i++) { html += '<div class="cal-panel__day cal-panel__day--other"></div>'; }
for (var d = 1; d <= daysInMonth; d++) {
var cls = 'cal-panel__day';
if (calViewYear === today.getFullYear() && calViewMonth === today.getMonth() && d === today.getDate()) cls += ' cal-panel__day--today';
if (calViewYear === currentDate.getFullYear() && calViewMonth === currentDate.getMonth() && d === currentDate.getDate()) cls += ' cal-panel__day--selected';
html += '<div class="' + cls + '" onclick="selectCalDay(event,' + d + ')">' + d + '</div>';
}
document.getElementById('calGrid').innerHTML = html;
}
function selectCalDay(e, day) {
e.stopPropagation();
currentDate = new Date(calViewYear, calViewMonth, day);
calViewYear = currentDate.getFullYear();
calViewMonth = currentDate.getMonth();
render();
document.getElementById('calPanel').classList.remove('active');
}
document.addEventListener('click', function(e) {
if (!e.target.closest('.date-nav') && !e.target.closest('.cal-panel')) {
document.getElementById('calPanel').classList.remove('active');
}
});
/* 初始化渲染 */
render();
</script>
</body>
</html>
@@ -0,0 +1,269 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 员工健康档案 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 员工卡片 */
.emp-card { background: linear-gradient(135deg,#1677ff,#0958d9); padding: 16px 20px; color: #fff; }
.emp-card__row { display: flex; align-items: center; gap: 12px; }
.emp-card__avatar { width: 48px; height: 48px; border-radius: 50%; background: rgba(255,255,255,0.25); border: 2px solid rgba(255,255,255,0.4); display: flex; align-items: center; justify-content: center; font-size: 24px; flex-shrink: 0; }
.emp-card__name { font-size: 18px; font-weight: 700; }
.emp-card__meta { font-size: 12px; color: rgba(255,255,255,0.85); margin-top: 2px; }
.emp-card__tags { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.emp-card__tag { font-size: 11px; padding: 3px 10px; border-radius: 12px; background: rgba(255,255,255,0.2); }
/* 卡片区块 */
.card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.card__title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 10px; display: flex; align-items: center; gap: 6px; }
.card__title .readonly { font-size: 10px; color: #999; font-weight: 400; background: #f5f5f5; padding: 1px 6px; border-radius: 8px; }
/* 关键摘要 */
.alert-item { display: flex; align-items: flex-start; gap: 8px; padding: 8px 0; border-bottom: 1px solid #f5f5f5; }
.alert-item:last-child { border-bottom: none; }
.alert-item__label { font-size: 12px; color: #999; width: 64px; flex-shrink: 0; margin-top: 2px; }
.alert-item__tags { flex: 1; display: flex; flex-wrap: wrap; gap: 6px; }
.atag { font-size: 12px; padding: 3px 10px; border-radius: 12px; }
.atag--danger { background: #fff1f0; color: #f5222d; }
.atag--warn { background: #fff7e6; color: #fa8c16; }
.atag--blue { background: #f0f7ff; color: #1677ff; }
.atag--normal { background: #f6ffed; color: #52c41a; }
/* 信息行 */
.info-row { display: flex; align-items: center; justify-content: space-between; padding: 9px 0; border-bottom: 0.5px solid #f5f5f5; }
.info-row:last-child { border-bottom: none; }
.info-row .i-label { font-size: 13px; color: #666; }
.info-row .i-value { font-size: 13px; color: #333; font-weight: 500; }
.info-row .i-value .i-unit { font-size: 11px; color: #999; margin-left: 2px; }
/* 标签组 */
.tag-group { display: flex; flex-wrap: wrap; gap: 6px; }
.tag-group .tg { font-size: 12px; padding: 4px 10px; border-radius: 12px; background: #f0f7ff; color: #1677ff; }
.tag-group .tg.warn { background: #fff7e6; color: #fa8c16; }
.tag-group .tg.danger { background: #fff1f0; color: #f5222d; }
.tag-group .tg.green { background: #f6ffed; color: #52c41a; }
/* 子标签 */
.sub-label { font-size: 12px; color: #999; margin-bottom: 6px; }
.sub-block { padding: 8px 0; border-bottom: 0.5px solid #f5f5f5; }
.sub-block:last-child { border-bottom: none; }
/* 餐次配比 */
.ratio-bar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; background: #f0f0f0; margin-bottom: 10px; }
.ratio-bar .ratio-seg { height: 100%; }
.ratio-list { display: flex; }
.ratio-list .ratio-item { flex: 1; display: flex; align-items: center; gap: 4px; font-size: 12px; }
.ratio-list .ratio-item .r-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ratio-list .ratio-item .r-name { color: #999; }
.ratio-list .ratio-item .r-val { color: #333; font-weight: 600; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<!-- [交互] 点击返回上一页 -->
<button class="nav-back" onclick="history.back()">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">员工健康档案</span>
</div>
<div class="scroll-content">
<!-- 员工卡片 -->
<div class="emp-card">
<div class="emp-card__row">
<div class="emp-card__avatar">👩</div>
<div>
<div class="emp-card__name">张小红</div>
<div class="emp-card__meta">女 · 32岁 · 公司机关 · 办公室 · 162cm · 67.2kg · BMI 25.6</div>
</div>
</div>
<div class="emp-card__tags">
<span class="emp-card__tag">减脂需求</span>
<span class="emp-card__tag">中度活动</span>
</div>
</div>
<!-- 关键摘要(营养师定制方案重点参考) -->
<div class="card" style="border-left:3px solid #1677ff;">
<div class="card__title">🎯 方案定制关键信息</div>
<div class="alert-item">
<span class="alert-item__label">体检异常</span>
<div class="alert-item__tags">
<span class="atag atag--warn">尿酸 380 偏高</span>
<span class="atag atag--normal">血压/血糖正常</span>
</div>
</div>
<div class="alert-item">
<span class="alert-item__label">疾病史</span>
<div class="alert-item__tags">
<span class="atag atag--danger">胃炎</span>
<span class="atag atag--danger">高尿酸</span>
</div>
</div>
<div class="alert-item">
<span class="alert-item__label">用药情况</span>
<div class="alert-item__tags">
<span class="atag atag--blue">别嘌醇片</span>
<span class="atag atag--blue">依那普利</span>
</div>
</div>
<div class="alert-item">
<span class="alert-item__label">过敏原</span>
<div class="alert-item__tags">
<span class="atag atag--danger">🥜 花生</span>
<span class="atag atag--danger">🦐 海鲜</span>
</div>
</div>
<div class="alert-item">
<span class="alert-item__label">饮食禁忌</span>
<div class="alert-item__tags">
<span class="atag atag--warn">🌶️ 少辣</span>
<span class="atag atag--warn">🧂 低盐</span>
<span class="atag atag--warn">🍬 控糖</span>
</div>
</div>
</div>
<!-- 1. 身体指标 -->
<div class="card">
<div class="card__title">📏 身体指标</div>
<div class="info-row"><span class="i-label">身高</span><span class="i-value">172<span class="i-unit">cm</span></span></div>
<div class="info-row"><span class="i-label">体重</span><span class="i-value">68<span class="i-unit">kg</span></span></div>
<div class="info-row"><span class="i-label">BMI</span><span class="i-value">23.0 <span style="color:#52c41a;font-size:11px;">正常</span></span></div>
<div class="info-row"><span class="i-label">体脂率</span><span class="i-value">18.5% <span style="color:#52c41a;font-size:11px;">标准</span></span></div>
<div class="info-row"><span class="i-label">活动水平</span><span class="i-value">中度活动<span class="i-unit">每周3-5次</span></span></div>
</div>
<!-- 2. 体检信息 -->
<div class="card">
<div class="card__title">🩺 体检信息<span class="readonly">只读</span></div>
<div class="info-row"><span class="i-label">体检日期</span><span class="i-value">2026-03-15</span></div>
<div class="info-row"><span class="i-label">血压</span><span class="i-value">125/80<span class="i-unit">mmHg</span></span></div>
<div class="info-row"><span class="i-label">空腹血糖</span><span class="i-value">5.2<span class="i-unit">mmol/L</span></span></div>
<div class="info-row"><span class="i-label">血脂</span><span class="i-value">正常</span></div>
<div class="info-row"><span class="i-label">尿酸</span><span class="i-value" style="color:#fa8c16;">380<span class="i-unit">μmol/L</span> <span style="color:#fa8c16;font-size:11px;">偏高</span></span></div>
<div class="info-row"><span class="i-label">肝功能</span><span class="i-value">正常</span></div>
<div class="info-row"><span class="i-label">肾功能</span><span class="i-value">正常</span></div>
</div>
<!-- 3. 疾病信息 -->
<div class="card">
<div class="card__title">🏥 疾病信息</div>
<div class="sub-block">
<div class="sub-label">疾病史</div>
<div class="tag-group"><span class="tg danger">胃炎</span><span class="tg danger">高尿酸</span></div>
</div>
<div class="sub-block">
<div class="sub-label">用药情况</div>
<div class="tag-group"><span class="tg">别嘌醇片</span><span class="tg">依那普利</span></div>
</div>
<div class="sub-block">
<div class="sub-label">家族病史</div>
<div class="tag-group"><span class="tg warn">高血压</span><span class="tg warn">糖尿病</span></div>
</div>
</div>
<!-- 4. 口味偏好 -->
<div class="card">
<div class="card__title">👅 口味偏好</div>
<div class="sub-block">
<div class="sub-label">口味偏好</div>
<div class="tag-group"><span class="tg">偏辣</span></div>
</div>
<div class="sub-block">
<div class="sub-label">地域菜系</div>
<div class="tag-group"><span class="tg">川菜</span><span class="tg">湘菜</span></div>
</div>
</div>
<!-- 5. 禁忌关联 -->
<div class="card">
<div class="card__title">🚫 禁忌关联</div>
<div class="sub-block">
<div class="sub-label">饮食禁忌</div>
<div class="tag-group"><span class="tg warn">🌶️ 少辣</span><span class="tg warn">🧂 低盐</span><span class="tg warn">🍬 控糖</span></div>
</div>
<div class="sub-block">
<div class="sub-label">过敏原</div>
<div class="tag-group"><span class="tg danger">🥜 花生</span><span class="tg danger">🦐 海鲜</span></div>
</div>
</div>
<!-- 6. 动态生理 -->
<div class="card">
<div class="card__title">📊 动态生理<span class="readonly">只读</span></div>
<div class="info-row"><span class="i-label">日均运动量</span><span class="i-value">6000步/日</span></div>
<div class="info-row"><span class="i-label">静息心率</span><span class="i-value">68<span class="i-unit">bpm</span></span></div>
<div class="info-row"><span class="i-label">平均睡眠</span><span class="i-value">7.5h</span></div>
<div class="info-row"><span class="i-label">压力指数</span><span class="i-value"></span></div>
<div class="info-row"><span class="i-label">数据来源</span><span class="i-value">智能手环</span></div>
</div>
<!-- 7. 菜品偏好 -->
<div class="card">
<div class="card__title">🍲 菜品偏好</div>
<div class="sub-block">
<div class="sub-label">常点菜品</div>
<div class="tag-group"><span class="tg green">宫保鸡丁</span><span class="tg green">清炒西兰花</span><span class="tg green">杂粮饭</span></div>
</div>
<div class="sub-block">
<div class="sub-label">忌口菜品</div>
<div class="tag-group"><span class="tg warn">油炸花生</span></div>
</div>
</div>
<!-- 8. 妈妈味道 -->
<div class="card">
<div class="card__title">🏡 妈妈味道</div>
<div class="info-row"><span class="i-label">家乡</span><span class="i-value">四川成都</span></div>
<div class="sub-block">
<div class="sub-label">口味标签</div>
<div class="tag-group"><span class="tg warn">麻辣</span><span class="tg warn">红油</span><span class="tg warn">鲜香</span></div>
</div>
<div class="sub-block">
<div class="sub-label">思乡菜清单</div>
<div class="tag-group"><span class="tg warn">回锅肉</span><span class="tg warn">麻婆豆腐</span><span class="tg warn">水煮鱼</span></div>
</div>
</div>
<!-- 9. 餐次配比 -->
<div class="card">
<div class="card__title">⚖️ 餐次配比</div>
<div class="ratio-bar">
<span class="ratio-seg" style="width:30%; background:#FFB84C;"></span>
<span class="ratio-seg" style="width:40%; background:#52C41A;"></span>
<span class="ratio-seg" style="width:30%; background:#1677FF;"></span>
</div>
<div class="ratio-list">
<div class="ratio-item"><span class="r-dot" style="background:#FFB84C;"></span><span class="r-name">早餐</span><span class="r-val">30%</span></div>
<div class="ratio-item"><span class="r-dot" style="background:#52C41A;"></span><span class="r-name">午餐</span><span class="r-val">40%</span></div>
<div class="ratio-item"><span class="r-dot" style="background:#1677FF;"></span><span class="r-name">晚餐</span><span class="r-val">30%</span></div>
</div>
</div>
<div style="height:16px;"></div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
</script>
</body>
</html>
@@ -0,0 +1,206 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 员工营养管理 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 搜索与筛选 */
.search-bar { background: #fff; padding: 10px 16px; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; }
.search-input { display: flex; align-items: center; gap: 8px; background: #f5f5f5; border-radius: 20px; padding: 8px 14px; }
.search-input input { flex: 1; border: none; background: none; font-size: 14px; outline: none; color: #1a1a1a; }
.filter-row { display: flex; gap: 8px; margin-top: 8px; }
.filter-chip { flex: 1; text-align: center; font-size: 12px; padding: 6px 0; border-radius: 16px; background: #f5f5f5; color: #666; cursor: pointer; }
.filter-chip.active { background: #e6f4ff; color: #1677ff; font-weight: 600; }
/* Tab */
.seg-tabs { display: flex; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; }
.seg-tab { flex: 1; text-align: center; padding: 12px 0; font-size: 14px; color: #666; cursor: pointer; border-bottom: 2px solid transparent; }
.seg-tab.active { color: #1677ff; border-bottom-color: #1677ff; font-weight: 600; }
.seg-tab .badge { display: inline-block; background: #e8e8e8; color: #666; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; padding: 0 4px; margin-left: 4px; vertical-align: middle; line-height: 16px; }
.seg-tab.active .badge { background: #e6f4ff; color: #1677ff; }
/* 员工卡片 */
.employee-card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); display: flex; align-items: center; gap: 10px; cursor: pointer; }
.employee-card:active { transform: scale(0.98); }
.employee-card__avatar { width: 44px; height: 44px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.employee-card__info { flex: 1; min-width: 0; }
.employee-card__name { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.employee-card__meta { font-size: 12px; color: #999; margin-top: 3px; display: flex; gap: 8px; flex-wrap: wrap; }
.employee-card__rate { display: flex; align-items: center; gap: 6px; flex-shrink: 0; }
.employee-card__rate-num { font-size: 15px; font-weight: 700; }
.employee-card__rate-num--good { color: #52c41a; }
.employee-card__rate-num--bad { color: #ff4d4f; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 10px; font-weight: 600; }
.tag-green { background: #f6ffed; color: #52c41a; }
.tag-orange { background: #fff7e6; color: #fa8c16; }
.tag-red { background: #fff1f0; color: #ff4d4f; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">员工营养管理</span>
</div>
<!-- 搜索与筛选 -->
<div class="search-bar">
<div class="search-input">
<span style="font-size:14px;">🔍</span>
<input type="text" placeholder="搜索员工姓名 / 工号" />
</div>
<div class="filter-row">
<div class="filter-chip active" onclick="filterChip(this)">全部单位</div>
<div class="filter-chip" onclick="filterChip(this)">机关</div>
<div class="filter-chip" onclick="filterChip(this)">采油一厂</div>
<div class="filter-chip" onclick="filterChip(this)">信息中心</div>
</div>
</div>
<!-- Tab:全部 / 达标 / 未达标 -->
<div class="seg-tabs">
<div class="seg-tab active" onclick="switchTab(this,'panel-all')">全部<span class="badge">86</span></div>
<div class="seg-tab" onclick="switchTab(this,'panel-good')">达标<span class="badge">62</span></div>
<div class="seg-tab" onclick="switchTab(this,'panel-bad')">未达标<span class="badge">24</span></div>
</div>
<div class="scroll-content">
<!-- 全部列表 -->
<div id="panel-all">
<!-- [交互] 点击跳转至: ./employee-detail.html -->
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#ffe0e0,#ffb3b3);">👩</div>
<div class="employee-card__info">
<div class="employee-card__name">张小红</div>
<div class="employee-card__meta"><span>女 · 32岁</span><span>公司机关 · 办公室</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--bad">68%</span><span class="tag tag-red">未达标</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#e8f4ff,#bdd7ff);">👨</div>
<div class="employee-card__info">
<div class="employee-card__name">李建国</div>
<div class="employee-card__meta"><span>男 · 45岁</span><span>采油一厂 · 技术部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--bad">71%</span><span class="tag tag-orange">待干预</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">👩</div>
<div class="employee-card__info">
<div class="employee-card__name">王芳</div>
<div class="employee-card__meta"><span>女 · 28岁</span><span>信息技术中心 · 数据部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--good">92%</span><span class="tag tag-green">达标</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#e8f4ff,#bdd7ff);">👨</div>
<div class="employee-card__info">
<div class="employee-card__name">陈伟</div>
<div class="employee-card__meta"><span>男 · 36岁</span><span>安全环保部 · 安环部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--good">88%</span><span class="tag tag-green">达标</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#fff7e6,#ffd591);">👨</div>
<div class="employee-card__info">
<div class="employee-card__name">赵志强</div>
<div class="employee-card__meta"><span>男 · 61岁</span><span>公司机关 · 后勤部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--bad">59%</span><span class="tag tag-red">未达标</span></div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 达标列表 -->
<div id="panel-good" style="display:none;">
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">👩</div>
<div class="employee-card__info">
<div class="employee-card__name">王芳</div>
<div class="employee-card__meta"><span>女 · 28岁</span><span>信息技术中心 · 数据部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--good">92%</span><span class="tag tag-green">达标</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#e8f4ff,#bdd7ff);">👨</div>
<div class="employee-card__info">
<div class="employee-card__name">陈伟</div>
<div class="employee-card__meta"><span>男 · 36岁</span><span>安全环保部 · 安环部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--good">88%</span><span class="tag tag-green">达标</span></div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 未达标列表 -->
<div id="panel-bad" style="display:none;">
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#ffe0e0,#ffb3b3);">👩</div>
<div class="employee-card__info">
<div class="employee-card__name">张小红</div>
<div class="employee-card__meta"><span>女 · 32岁</span><span>公司机关 · 办公室</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--bad">68%</span><span class="tag tag-red">未达标</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#e8f4ff,#bdd7ff);">👨</div>
<div class="employee-card__info">
<div class="employee-card__name">李建国</div>
<div class="employee-card__meta"><span>男 · 45岁</span><span>采油一厂 · 技术部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--bad">71%</span><span class="tag tag-orange">待干预</span></div>
</div>
<div class="employee-card" onclick="location.href='./employee-detail.html'">
<div class="employee-card__avatar" style="background:linear-gradient(135deg,#fff7e6,#ffd591);">👨</div>
<div class="employee-card__info">
<div class="employee-card__name">赵志强</div>
<div class="employee-card__meta"><span>男 · 61岁</span><span>公司机关 · 后勤部</span></div>
</div>
<div class="employee-card__rate"><span class="employee-card__rate-num employee-card__rate-num--bad">59%</span><span class="tag tag-red">未达标</span></div>
</div>
<div style="height:16px;"></div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* Tab 切换 */
function switchTab(el, panelId) {
el.closest('.seg-tabs').querySelectorAll('.seg-tab').forEach(function(t) { t.classList.remove('active'); });
el.classList.add('active');
['panel-all','panel-good','panel-bad'].forEach(function(id) {
document.getElementById(id).style.display = id === panelId ? 'block' : 'none';
});
}
/* 单位筛选 */
function filterChip(el) {
el.parentElement.querySelectorAll('.filter-chip').forEach(function(c) { c.classList.remove('active'); });
el.classList.add('active');
}
</script>
</body>
</html>
@@ -0,0 +1,229 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 工作台主页 | 健康CQ原型</title>
<style>
/* 公共重置与布局 */
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
/* 手机壳容器 */
.phone-shell { width: 390px; height: 844px; background: #fff; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
/* 状态栏 */
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
/* 滚动内容区 */
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 底部Tab栏 */
.tab-bar { height: 83px; background: #fff; border-top: 1px solid #e8e8e8; display: flex; align-items: flex-start; padding-top: 8px; flex-shrink: 0; }
.tab-item { flex: 1; display: flex; flex-direction: column; align-items: center; gap: 4px; cursor: pointer; padding: 4px 0; position: relative; }
.tab-item .tab-icon { font-size: 22px; line-height: 1; }
.tab-item .tab-label { font-size: 10px; color: #999; font-weight: 500; }
.tab-item.active .tab-label { color: #1677ff; }
.tab-badge { position: absolute; top: 2px; right: 18px; background: #ff4d4f; color: #fff; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; display: flex; align-items: center; justify-content: center; padding: 0 4px; }
/* 分段Tab */
.seg-tabs { display: flex; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; }
.seg-tab { flex: 1; text-align: center; padding: 12px 0; font-size: 14px; color: #666; cursor: pointer; border-bottom: 2px solid transparent; transition: all 0.2s; }
.seg-tab.active { color: #1677ff; border-bottom-color: #1677ff; font-weight: 600; }
.seg-tab .badge { display: inline-block; background: #e8e8e8; color: #666; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; padding: 0 4px; margin-left: 4px; vertical-align: middle; line-height: 16px; }
.seg-tab.active .badge { background: #e6f4ff; color: #1677ff; }
/* 标签 */
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-blue { background: #e6f4ff; color: #1677ff; }
.tag-green { background: #f6ffed; color: #52c41a; }
.tag-orange { background: #fff7e6; color: #fa8c16; }
.tag-red { background: #fff1f0; color: #ff4d4f; }
.tag-gray { background: #f5f5f5; color: #999; }
/* 快捷入口网格 */
.quick-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 10px 16px 0; }
.quick-card { background: #fff; border-radius: 12px; padding: 14px; cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,0.06); display: flex; align-items: center; gap: 10px; transition: transform 0.15s; }
.quick-card:active { transform: scale(0.98); }
.quick-card__icon { width: 42px; height: 42px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.quick-card__info { flex: 1; min-width: 0; }
.quick-card__title { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.quick-card__desc { font-size: 11px; color: #999; margin-top: 2px; }
/* 咨询卡片 */
.consult-card { background: #fff; border-radius: 12px; margin: 10px 16px 0; padding: 14px; cursor: pointer; box-shadow: 0 1px 4px rgba(0,0,0,0.06); transition: transform 0.15s; }
.consult-card:active { transform: scale(0.98); }
.cc-top { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.cc-avatar { width: 42px; height: 42px; border-radius: 50%; background: linear-gradient(135deg, #e8f4ff, #bdd7ff); display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.cc-info { flex: 1; min-width: 0; }
.cc-name { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.cc-meta { font-size: 12px; color: #999; margin-top: 2px; }
.cc-bottom { display: flex; align-items: center; justify-content: space-between; }
.cc-preview { font-size: 13px; color: #666; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 210px; }
.cc-time { font-size: 12px; color: #bbb; flex-shrink: 0; }
.unread-dot { width: 8px; height: 8px; border-radius: 50%; background: #ff4d4f; flex-shrink: 0; }
/* 弹窗样式 */
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
</style>
</head>
<body>
<div class="phone-shell">
<!-- 状态栏 -->
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 蓝色渐变头部区域 -->
<div style="background:linear-gradient(135deg,#1677ff,#0958d9);padding:16px 20px 20px;flex-shrink:0;">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:14px;">
<div>
<div style="color:rgba(255,255,255,0.75);font-size:12px;margin-bottom:2px;">你好,李营养师</div>
<div style="color:#fff;font-size:20px;font-weight:700;">工作台</div>
</div>
<!-- [交互] 点击切换营养咨询服务状态 -->
<button id="wb-pause-btn" onclick="togglePause()" style="display:flex;align-items:center;gap:6px;background:rgba(255,255,255,0.2);border:1px solid rgba(255,255,255,0.4);border-radius:20px;padding:6px 14px;color:#fff;font-size:13px;cursor:pointer;">
<span id="pause-dot" style="width:8px;height:8px;border-radius:50%;background:#52c41a;display:inline-block;flex-shrink:0;"></span>
<span id="pause-label">咨询已开启</span>
</button>
</div>
<!-- 统计数字 -->
<div style="display:flex;">
<div style="flex:1;text-align:center;"><div style="color:#fff;font-size:22px;font-weight:700;">2</div><div style="color:rgba(255,255,255,0.75);font-size:11px;margin-top:2px;">营养咨询待回复</div></div>
<div style="width:1px;background:rgba(255,255,255,0.25);margin:4px 0;"></div>
<div style="flex:1;text-align:center;"><div style="color:#fff;font-size:22px;font-weight:700;">3</div><div style="color:rgba(255,255,255,0.75);font-size:11px;margin-top:2px;">方案待跟进</div></div>
<div style="width:1px;background:rgba(255,255,255,0.25);margin:4px 0;"></div>
<div style="flex:1;text-align:center;"><div style="color:#fff;font-size:22px;font-weight:700;">5</div><div style="color:rgba(255,255,255,0.75);font-size:11px;margin-top:2px;">食谱被引用</div></div>
</div>
</div>
<div class="scroll-content">
<!-- 快捷功能入口(2 个大 tab -->
<div style="display:flex;gap:10px;margin:10px 16px 0;">
<!-- [交互] 点击跳转至: ./employee-list.html -->
<div onclick="location.href='./employee-list.html'" style="flex:1;background:#fff;border-radius:12px;padding:16px 14px;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,0.06);text-align:center;transition:transform 0.15s;">
<div style="width:48px;height:48px;border-radius:14px;background:linear-gradient(135deg,#e6f4ff,#b7d8ff);display:flex;align-items:center;justify-content:center;font-size:24px;margin:0 auto 8px;">👥</div>
<div style="font-size:15px;font-weight:600;color:#1a1a1a;">员工营养管理</div>
<div style="font-size:11px;color:#999;margin-top:4px;">达标监控 · 一对一指导</div>
</div>
<!-- [交互] 点击跳转至: ./recipe-list.html -->
<div onclick="location.href='./recipe-list.html'" style="flex:1;background:#fff;border-radius:12px;padding:16px 14px;cursor:pointer;box-shadow:0 1px 4px rgba(0,0,0,0.06);text-align:center;transition:transform 0.15s;">
<div style="width:48px;height:48px;border-radius:14px;background:linear-gradient(135deg,#fff7e6,#ffd591);display:flex;align-items:center;justify-content:center;font-size:24px;margin:0 auto 8px;">🥗</div>
<div style="font-size:15px;font-weight:600;color:#1a1a1a;">我的食谱</div>
<div style="font-size:11px;color:#999;margin-top:4px;">按周发布 · 引用查看</div>
</div>
</div>
<!-- 营养咨询列表 -->
<div id="consult-list" style="margin-top:4px;">
<div class="seg-tabs">
<div class="seg-tab active" onclick="switchWorkTab(this,'wb-text-pending')">待回复<span class="badge">2</span></div>
<div class="seg-tab" onclick="switchWorkTab(this,'wb-text-ongoing')">进行中<span class="badge" style="background:#fff7e6;color:#fa8c16;">1</span></div>
<div class="seg-tab" onclick="switchWorkTab(this,'wb-text-done')">已结束</div>
</div>
<!-- 待回复列表 -->
<div id="wb-text-pending">
<!-- [交互] 点击跳转至: ./consult-chat.html -->
<div class="consult-card" onclick="location.href='./consult-chat.html'">
<div class="cc-top"><div class="cc-avatar">👩</div><div class="cc-info"><div class="cc-name">张小红</div><div class="cc-meta">女 · 32岁 · 减脂需求</div></div><span class="tag tag-red">待回复</span></div>
<div class="cc-bottom"><div class="cc-preview">食堂太油了,想请教怎么吃才能减脂...</div><div style="display:flex;align-items:center;gap:6px;"><span class="cc-time">10:23</span><span class="unread-dot"></span></div></div>
</div>
<!-- [交互] 点击跳转至: ./consult-chat.html -->
<div class="consult-card" onclick="location.href='./consult-chat.html'">
<div class="cc-top"><div class="cc-avatar">👨</div><div class="cc-info"><div class="cc-name">李建国</div><div class="cc-meta">男 · 45岁 · 高血脂</div></div><span class="tag tag-red">待回复</span></div>
<div class="cc-bottom"><div class="cc-preview">血脂偏高,日常饮食有什么忌口...</div><div style="display:flex;align-items:center;gap:6px;"><span class="cc-time">09:55</span><span class="unread-dot"></span></div></div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 进行中列表 -->
<div id="wb-text-ongoing" style="display:none;">
<!-- [交互] 点击跳转至: ./consult-chat.html -->
<div class="consult-card" onclick="location.href='./consult-chat.html'">
<div class="cc-top"><div class="cc-avatar">👨</div><div class="cc-info"><div class="cc-name">陈伟</div><div class="cc-meta">男 · 36岁 · 增肌需求</div></div><span class="tag tag-blue">进行中</span></div>
<div class="cc-bottom"><div class="cc-preview">好的,我按您给的食谱吃一周看看</div><span class="cc-time">昨天</span></div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 已结束列表 -->
<div id="wb-text-done" style="display:none;">
<!-- [交互] 点击跳转至: ./consult-chat-done.html -->
<div class="consult-card" onclick="location.href='./consult-chat-done.html'">
<div class="cc-top"><div class="cc-avatar">👨</div><div class="cc-info"><div class="cc-name">赵磊</div><div class="cc-meta">男 · 35岁</div></div><span class="tag tag-green">已完成</span></div>
<div class="cc-bottom"><div class="cc-preview">谢谢营养师,方案很实用</div><span class="cc-time">08:40</span></div>
</div>
<div style="height:16px;"></div>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 服务状态切换确认弹窗 -->
<div id="modal-pause" class="modal-center">
<div class="modal-box">
<div class="modal-title" id="pause-modal-title">关闭咨询</div>
<div class="modal-body" id="pause-modal-body">是否要关闭营养咨询?关闭后,员工无法发起营养咨询。</div>
<div class="modal-actions">
<button onclick="closeModal('modal-pause')">取消</button>
<button onclick="confirmTogglePause()">确认</button>
</div>
</div>
</div>
<!-- 底部5Tab导航栏 -->
<div class="tab-bar">
<div class="tab-item active" onclick="location.href='./index.html'"><span class="tab-icon">🏥</span><span class="tab-label">工作台</span><span class="tab-badge">2</span></div>
<div class="tab-item" onclick="location.href='../knowledge/index.html'"><span class="tab-icon">📚</span><span class="tab-label">知识库</span></div>
<div class="tab-item" onclick="location.href='../../ai-assistant/index.html'"><span class="tab-icon">🤖</span><span class="tab-label">AI助手</span></div>
<div class="tab-item" onclick="location.href='../../message/index.html'"><span class="tab-icon">💬</span><span class="tab-label">消息</span><span class="tab-badge">2</span></div>
<div class="tab-item" onclick="location.href='../profile/index.html'"><span class="tab-icon">👤</span><span class="tab-label">我的</span></div>
</div>
</div>
<script>
/* 标记当前角色为营养师,供共用页面(消息、AI助手)判断返回目标 */
sessionStorage.setItem('appRole', 'nutritionist');
/**
* 切换二级Tab(待回复/进行中/已结束)
* @param {HTMLElement} el - 被点击的Tab元素
* @param {string} panelId - 目标面板ID
*/
function switchWorkTab(el, panelId) {
el.closest('.seg-tabs').querySelectorAll('.seg-tab').forEach(function(t) { t.classList.remove('active'); });
el.classList.add('active');
var scrollContent = el.closest('.seg-tabs').nextElementSibling;
Array.from(scrollContent.children).forEach(function(p) {
if (p.id) p.style.display = p.id === panelId ? 'block' : 'none';
});
}
/* 服务状态切换 */
var isPaused = false;
function togglePause() {
var title = isPaused ? '开启咨询' : '关闭咨询';
var body = isPaused ? '是否要开启营养咨询?开启后,员工可发起营养咨询。' : '是否要关闭营养咨询?关闭后,员工无法发起营养咨询。';
document.getElementById('pause-modal-title').textContent = title;
document.getElementById('pause-modal-body').textContent = body;
openModal('modal-pause');
}
function confirmTogglePause() {
isPaused = !isPaused;
var bg = isPaused ? '#ff4d4f' : '#52c41a';
var text = isPaused ? '咨询已关闭' : '咨询已开启';
document.getElementById('pause-dot').style.background = bg;
document.getElementById('pause-label').textContent = text;
closeModal('modal-pause');
}
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
</script>
</body>
</html>
@@ -0,0 +1,407 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 营养方案详情 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 头部 */
.plan-header { background: linear-gradient(135deg,#1677ff,#0958d9); padding: 16px 20px; color: #fff; }
.plan-header__top { display: flex; align-items: center; gap: 12px; }
.plan-header__avatar { width: 48px; height: 48px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-size: 24px; flex-shrink: 0; background: rgba(255,255,255,0.25); border: 2px solid rgba(255,255,255,0.4); }
.plan-header__name { font-size: 17px; font-weight: 700; }
.plan-header__meta { font-size: 12px; color: rgba(255,255,255,0.85); margin-top: 2px; }
.plan-header__tag { margin-left: auto; font-size: 12px; padding: 4px 12px; border-radius: 14px; background: rgba(255,255,255,0.2); }
/* 卡片 */
.card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.card__title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 10px; display: flex; align-items: center; }
/* 营养目标 */
.goal-row { display: flex; }
.goal-item { flex: 1; text-align: center; }
.goal-item + .goal-item { border-left: 1px solid #f0f0f0; }
.goal-item__val { font-size: 16px; font-weight: 700; color: #1677ff; }
.goal-item__label { font-size: 11px; color: #999; margin-top: 2px; }
/* 三大营养素 */
.macro-bar { display: flex; height: 24px; border-radius: 6px; overflow: hidden; margin-bottom: 8px; }
.macro-bar__seg { display: flex; align-items: center; justify-content: center; font-size: 11px; color: #fff; font-weight: 600; }
.macro-legend { display: flex; gap: 12px; }
.macro-legend__item { display: flex; align-items: center; gap: 4px; font-size: 11px; color: #666; }
.macro-legend__dot { width: 8px; height: 8px; border-radius: 50%; }
/* 一周饮食安排(按天折叠,每天三餐,食物含分量与热量) */
.day-card { background: #fff; border: 1px solid #e8e8e8; border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
.day-card:last-child { margin-bottom: 0; }
.day-header { display: flex; align-items: center; justify-content: space-between; padding: 12px; cursor: pointer; }
.day-header__day { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.day-header__summary { font-size: 12px; color: #999; }
.day-header__kcal { font-size: 12px; color: #fa8c16; font-weight: 600; }
.day-header .arrow { transition: transform .2s; flex-shrink: 0; }
.day-header .arrow.open { transform: rotate(180deg); }
.day-body { display: none; padding: 0 12px 12px; }
.day-body.open { display: block; }
.meal-block { background: #fafafa; border-radius: 8px; padding: 10px; margin-bottom: 8px; }
.meal-block:last-child { margin-bottom: 0; }
.meal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.meal-head__name { font-size: 13px; font-weight: 600; color: #1a1a1a; }
.meal-head__subtotal { font-size: 12px; color: #fa8c16; font-weight: 600; }
.food-row { display: flex; align-items: center; gap: 6px; padding: 6px 0; border-bottom: 1px dashed #f0f0f0; }
.food-row:last-child { border-bottom: none; }
.food-row__name { flex: 1; font-size: 13px; color: #333; }
.food-row__amount { font-size: 12px; color: #666; width: 44px; text-align: right; flex-shrink: 0; }
.food-row__kcal { font-size: 12px; color: #fa8c16; font-weight: 600; width: 56px; text-align: right; flex-shrink: 0; }
/* 执行进度 */
.checkin-row { display: flex; gap: 6px; }
.checkin-day { flex: 1; text-align: center; }
.checkin-day__dot { width: 26px; height: 26px; border-radius: 50%; margin: 0 auto; display: flex; align-items: center; justify-content: center; font-size: 12px; }
.checkin-day__dot--done { background: #52c41a; color: #fff; }
.checkin-day__dot--today { background: #e6f4ff; color: #1677ff; border: 1px solid #1677ff; }
.checkin-day__dot--pending { background: #f5f5f5; color: #bbb; }
.checkin-day__label { font-size: 10px; color: #999; margin-top: 4px; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-red { background: #fff1f0; color: #ff4d4f; }
.tag-orange { background: #fff7e6; color: #fa8c16; }
/* 底部弹层 */
.sheet-mask { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.45); z-index: 300; align-items: flex-end; justify-content: center; }
.sheet-mask.active { display: flex; }
.sheet-panel { width: 100%; max-height: 80%; background: #fff; border-radius: 16px 16px 0 0; display: flex; flex-direction: column; overflow: hidden; }
.sheet-header { display: flex; align-items: center; justify-content: space-between; padding: 14px 16px; border-bottom: 0.5px solid #f0f0f0; flex-shrink: 0; }
.sheet-header .s-cancel { font-size: 14px; color: #999; cursor: pointer; background: none; border: none; }
.sheet-header .s-title { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.sheet-header .s-save { font-size: 14px; color: #1677ff; font-weight: 600; cursor: pointer; background: none; border: none; }
.sheet-body { padding: 12px 16px 20px; overflow-y: auto; flex: 1; }
.sheet-body::-webkit-scrollbar { display: none; }
.sheet-tip { font-size: 12px; color: #999; background: #fafafa; border-radius: 8px; padding: 10px 12px; line-height: 1.6; margin-bottom: 12px; }
.adj-meal { margin-bottom: 14px; }
.adj-meal__label { font-size: 13px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; }
.adj-dish { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; padding: 5px 10px; border-radius: 14px; background: #f0f6ff; color: #1677ff; margin: 0 6px 6px 0; cursor: pointer; }
.adj-dish .x { color: #999; font-size: 12px; line-height: 1; }
.adj-add { display: inline-flex; align-items: center; gap: 4px; font-size: 12px; padding: 5px 12px; border-radius: 14px; border: 1px dashed #1677ff; color: #1677ff; margin-bottom: 6px; cursor: pointer; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./employee-detail.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">营养方案详情</span>
</div>
<div class="scroll-content">
<!-- 头部 -->
<div class="plan-header">
<div class="plan-header__top">
<div class="plan-header__avatar">👩</div>
<div>
<div class="plan-header__name">张小红</div>
<div class="plan-header__meta">减脂期一周饮食方案 · 女 32岁</div>
</div>
<span class="plan-header__tag">执行中</span>
</div>
</div>
<!-- 方案依据(健康档案摘要) -->
<div class="card" style="border-left:3px solid #1677ff;">
<div class="card__title">🎯 方案依据<span style="font-size:12px;color:#1677ff;font-weight:400;margin-left:auto;cursor:pointer;" onclick="location.href='./employee-health.html'">查看完整健康档案 </span></div>
<div style="display:flex;flex-wrap:wrap;gap:6px;">
<span class="tag tag-orange">尿酸 380 偏高</span>
<span class="tag tag-red">胃炎</span>
<span class="tag tag-red">高尿酸</span>
<span class="tag tag-red">过敏原:花生</span>
<span class="tag tag-red">过敏原:海鲜</span>
<span class="tag tag-orange">少辣 · 低盐 · 控糖</span>
</div>
</div>
<!-- 营养目标 -->
<div class="card">
<div class="card__title">营养目标</div>
<div class="goal-row">
<div class="goal-item"><div class="goal-item__val">1400</div><div class="goal-item__label">热量 kcal/日</div></div>
<div class="goal-item"><div class="goal-item__val">75</div><div class="goal-item__label">蛋白质 g</div></div>
<div class="goal-item"><div class="goal-item__val">30</div><div class="goal-item__label">脂肪 g</div></div>
<div class="goal-item"><div class="goal-item__val">190</div><div class="goal-item__label">碳水 g</div></div>
</div>
</div>
<!-- 三大营养素占比 -->
<div class="card">
<div class="card__title">三大营养素占比</div>
<div class="macro-bar">
<div class="macro-bar__seg" style="width:25%;background:#1677ff;">蛋白25%</div>
<div class="macro-bar__seg" style="width:20%;background:#fa8c16;">脂肪20%</div>
<div class="macro-bar__seg" style="width:55%;background:#52c41a;">碳水55%</div>
</div>
<div class="macro-legend">
<span class="macro-legend__item"><span class="macro-legend__dot" style="background:#1677ff;"></span>蛋白质</span>
<span class="macro-legend__item"><span class="macro-legend__dot" style="background:#fa8c16;"></span>脂肪</span>
<span class="macro-legend__item"><span class="macro-legend__dot" style="background:#52c41a;"></span>碳水化合物</span>
</div>
</div>
<!-- 饮食禁忌 -->
<div class="card">
<div class="card__title">饮食禁忌</div>
<div style="display:flex;gap:6px;">
<span class="tag tag-red">高糖</span>
<span class="tag tag-red">高脂</span>
<span class="tag tag-orange">高盐</span>
</div>
</div>
<!-- 一周饮食安排 -->
<div class="card">
<div class="card__title">一周饮食安排<span style="font-size:10px;color:#52c41a;font-weight:400;background:#f6ffed;padding:2px 8px;border-radius:8px;margin-left:8px;">系统生成</span><span style="font-size:12px;color:#1677ff;font-weight:400;margin-left:auto;cursor:pointer;" onclick="openSheet('sheet-adjust')">微调食谱 </span></div>
<div id="day-list"></div>
</div>
<!-- 执行进度 -->
<div class="card">
<div class="card__title">执行进度<span style="font-size:12px;color:#999;font-weight:400;margin-left:8px;">第 3 天 / 7 天</span></div>
<div class="checkin-row">
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--done"></div><div class="checkin-day__label">周一</div></div>
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--done"></div><div class="checkin-day__label">周二</div></div>
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--today">3</div><div class="checkin-day__label">周三</div></div>
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--pending">4</div><div class="checkin-day__label">周四</div></div>
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--pending">5</div><div class="checkin-day__label">周五</div></div>
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--pending">6</div><div class="checkin-day__label">周六</div></div>
<div class="checkin-day"><div class="checkin-day__dot checkin-day__dot--pending">7</div><div class="checkin-day__label">周日</div></div>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 微调食谱底部弹层 -->
<div id="sheet-adjust" class="sheet-mask" onclick="if(event.target===this)closeSheet('sheet-adjust')">
<div class="sheet-panel" onclick="event.stopPropagation()">
<div class="sheet-header">
<button class="s-cancel" onclick="closeSheet('sheet-adjust')">取消</button>
<span class="s-title">微调一周食谱</span>
<button class="s-save" onclick="closeSheet('sheet-adjust');alert('食谱已微调(原型演示)')">保存</button>
</div>
<div class="sheet-body">
<div class="sheet-tip">系统已根据方案参数(1400kcal/日 · 蛋白25% · 脂肪20% · 碳水55% · 禁忌:高糖、高脂、高嘌呤)生成一周专属食谱,可替换任意餐品。</div>
<div id="adjust-list"></div>
</div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* ===== 一周专属食谱数据(每天三餐,每餐食物含分量与热量) ===== */
var WEEK = [
{ day: '周一', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '全麦面包', amount: 80, unit: 'g', kcal: 200 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '清蒸鲈鱼', amount: 150, unit: 'g', kcal: 160 },
{ name: '杂粮饭', amount: 200, unit: 'g', kcal: 240 },
{ name: '蒜蓉西兰花', amount: 150, unit: 'g', kcal: 60 },
{ name: '紫菜蛋花汤', amount: 200, unit: 'ml', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '香煎鸡胸', amount: 120, unit: 'g', kcal: 200 },
{ name: '蔬菜沙拉', amount: 200, unit: 'g', kcal: 80 },
{ name: '小米粥', amount: 200, unit: 'g', kcal: 120 }
]}
]},
{ day: '周二', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '燕麦牛奶', amount: 300, unit: 'ml', kcal: 220 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '白灼虾', amount: 150, unit: 'g', kcal: 140 },
{ name: '糙米饭', amount: 200, unit: 'g', kcal: 230 },
{ name: '清炒时蔬', amount: 150, unit: 'g', kcal: 55 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '蔬菜豆腐汤', amount: 300, unit: 'g', kcal: 150 },
{ name: '杂粮馒头', amount: 100, unit: 'g', kcal: 220 }
]}
]},
{ day: '周三', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '豆浆', amount: 250, unit: 'ml', kcal: 80 },
{ name: '蒸红薯', amount: 100, unit: 'g', kcal: 90 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '卤牛肉', amount: 100, unit: 'g', kcal: 160 },
{ name: '荞麦面', amount: 200, unit: 'g', kcal: 230 },
{ name: '凉拌黄瓜', amount: 150, unit: 'g', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '清炒时蔬', amount: 200, unit: 'g', kcal: 60 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '菌菇汤', amount: 200, unit: 'g', kcal: 50 }
]}
]},
{ day: '周四', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '杂粮粥', amount: 300, unit: 'g', kcal: 200 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '香煎鸡胸', amount: 150, unit: 'g', kcal: 250 },
{ name: '藜麦饭', amount: 150, unit: 'g', kcal: 180 },
{ name: '西兰花', amount: 150, unit: 'g', kcal: 60 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '虾仁沙拉', amount: 200, unit: 'g', kcal: 150 },
{ name: '全麦面包', amount: 50, unit: 'g', kcal: 120 }
]}
]},
{ day: '周五', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '全麦面包', amount: 80, unit: 'g', kcal: 200 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 },
{ name: '香蕉', amount: 100, unit: 'g', kcal: 90 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '清蒸鱼', amount: 150, unit: 'g', kcal: 160 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '凉拌木耳', amount: 100, unit: 'g', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '菌菇汤', amount: 300, unit: 'g', kcal: 120 },
{ name: '杂粮饭', amount: 150, unit: 'g', kcal: 180 }
]}
]},
{ day: '周六', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '燕麦', amount: 50, unit: 'g', kcal: 190 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '白灼虾', amount: 150, unit: 'g', kcal: 140 },
{ name: '杂粮饭', amount: 200, unit: 'g', kcal: 240 },
{ name: '蔬菜沙拉', amount: 150, unit: 'g', kcal: 60 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '蔬菜沙拉', amount: 200, unit: 'g', kcal: 80 },
{ name: '鸡胸肉', amount: 100, unit: 'g', kcal: 170 },
{ name: '玉米', amount: 100, unit: 'g', kcal: 110 }
]}
]},
{ day: '周日', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '豆浆', amount: 250, unit: 'ml', kcal: 80 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '卤牛肉', amount: 100, unit: 'g', kcal: 160 },
{ name: '糙米饭', amount: 200, unit: 'g', kcal: 230 },
{ name: '清炒时蔬', amount: 150, unit: 'g', kcal: 55 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '鸡胸沙拉', amount: 250, unit: 'g', kcal: 200 },
{ name: '小米粥', amount: 200, unit: 'g', kcal: 120 }
]}
]}
];
/* 计算某餐总热量 */
function mealSubtotal(di, mi) {
return WEEK[di].meals[mi].foods.reduce(function(s, f) { return s + f.kcal; }, 0);
}
/* 计算某天总热量 */
function dayTotal(di) {
return WEEK[di].meals.reduce(function(s, m, mi) { return s + mealSubtotal(di, mi); }, 0);
}
/* 某天三餐小计摘要 */
function daySummary(di) {
return WEEK[di].meals.map(function(m, mi) { return m.name.charAt(0) + mealSubtotal(di, mi); }).join(' · ');
}
/* 渲染一周饮食安排(折叠卡片,只读) */
function renderDayList() {
var html = '';
WEEK.forEach(function(day, di) {
html += '<div class="day-card">' +
'<div class="day-header" onclick="toggleDay(' + di + ')">' +
'<span class="day-header__day">' + day.day + '</span>' +
'<span class="day-header__summary">' + daySummary(di) + '</span>' +
'<span class="day-header__kcal">' + dayTotal(di) + ' kcal</span>' +
'<svg class="arrow" id="arrow-' + di + '" width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="#999" stroke-width="2"><path d="M4 6l4 4 4-4"/></svg>' +
'</div>' +
'<div class="day-body" id="day-body-' + di + '">' +
day.meals.map(function(m, mi) {
return '<div class="meal-block">' +
'<div class="meal-head"><span class="meal-head__name">' + m.icon + ' ' + m.name + '</span><span class="meal-head__subtotal">小计 ' + mealSubtotal(di, mi) + ' kcal</span></div>' +
m.foods.map(function(f) {
return '<div class="food-row"><span class="food-row__name">' + f.name + '</span><span class="food-row__amount">' + f.amount + f.unit + '</span><span class="food-row__kcal">' + f.kcal + ' kcal</span></div>';
}).join('') +
'</div>';
}).join('') +
'</div>' +
'</div>';
});
document.getElementById('day-list').innerHTML = html;
/* 默认展开周一 */
document.getElementById('day-body-0').classList.add('open');
document.getElementById('arrow-0').classList.add('open');
}
/* 渲染微调弹层(食物带分量与热量) */
function renderAdjustList() {
var html = '';
WEEK.forEach(function(day) {
html += '<div class="adj-meal"><div class="adj-meal__label">' + day.day + '</div>';
day.meals.forEach(function(m) {
m.foods.forEach(function(f) {
html += '<span class="adj-dish">' + m.name.charAt(0) + '·' + f.name + ' ' + f.amount + f.unit + '·' + f.kcal + 'kcal<span class="x">×</span></span>';
});
});
html += '<span class="adj-add"> 添加餐品</span></div>';
});
document.getElementById('adjust-list').innerHTML = html;
}
/* 折叠/展开某天 */
function toggleDay(di) {
var body = document.getElementById('day-body-' + di);
var arrow = document.getElementById('arrow-' + di);
body.classList.toggle('open');
arrow.classList.toggle('open');
}
/* 打开底部弹层 */
function openSheet(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
/* 关闭底部弹层 */
function closeSheet(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
/* 初始化渲染 */
renderDayList();
renderAdjustList();
</script>
</body>
</html>
@@ -0,0 +1,408 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 制定食谱 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 表单 */
.form-card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.form-card__title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 12px; }
.form-item { margin-bottom: 14px; }
.form-item:last-child { margin-bottom: 0; }
.form-item__label { font-size: 13px; font-weight: 600; color: #1a1a1a; margin-bottom: 8px; }
.form-item__label .req { color: #ff4d4f; margin-left: 2px; }
.form-input { width: 100%; border: 1px solid #e8e8e8; border-radius: 8px; padding: 10px 12px; font-size: 14px; outline: none; color: #1a1a1a; }
.form-input:focus { border-color: #1677ff; }
/* 分段选择 */
.seg-picker { display: flex; background: #f5f5f5; border-radius: 8px; padding: 3px; }
.seg-picker__opt { flex: 1; text-align: center; padding: 7px 0; font-size: 13px; color: #666; border-radius: 6px; cursor: pointer; }
.seg-picker__opt.active { background: #fff; color: #1677ff; font-weight: 600; box-shadow: 0 1px 4px rgba(0,0,0,0.1); }
/* 日期范围 */
.date-range { display: flex; align-items: center; gap: 8px; }
.date-range .form-input { flex: 1; text-align: center; }
.date-range .sep { color: #999; flex-shrink: 0; }
/* 餐次配置 */
.meal-item { border: 1px solid #e8e8e8; border-radius: 10px; padding: 12px; margin-bottom: 10px; }
.meal-item:last-child { margin-bottom: 0; }
.meal-item__head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 8px; }
.meal-item__name { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.meal-item__add { font-size: 12px; color: #1677ff; cursor: pointer; }
.meal-item__dishes { display: flex; flex-wrap: wrap; gap: 6px; }
.dish-chip { font-size: 11px; padding: 4px 10px; border-radius: 12px; background: #f0f6ff; color: #1677ff; }
/* 营养汇总 */
.nutri-summary { display: flex; gap: 8px; }
.nutri-summary__item { flex: 1; text-align: center; background: #fafafa; border-radius: 8px; padding: 8px 0; }
.nutri-summary__val { font-size: 14px; font-weight: 700; color: #1677ff; }
.nutri-summary__label { font-size: 10px; color: #999; margin-top: 2px; }
/* 底部操作 */
.bottom-bar { background: #fff; border-top: 1px solid #f0f0f0; padding: 10px 16px 14px; flex-shrink: 0; display: flex; gap: 10px; }
.btn-draft { flex: 1; padding: 12px; background: #fff; color: #1677ff; border: 1px solid #1677ff; border-radius: 10px; font-size: 15px; font-weight: 600; cursor: pointer; }
.btn-pub { flex: 1; padding: 12px; background: #1677ff; color: #fff; border: none; border-radius: 10px; font-size: 15px; font-weight: 600; cursor: pointer; }
.modal-center { display: none; position: absolute; inset: 0; background: rgba(0,0,0,0.5); z-index: 200; align-items: center; justify-content: center; }
.modal-center.active { display: flex; }
.modal-box { width: 280px; background: #fff; border-radius: 16px; overflow: hidden; }
.modal-box .modal-title { padding: 20px 20px 8px; font-size: 17px; font-weight: 700; text-align: center; color: #1a1a1a; }
.modal-box .modal-body { padding: 8px 20px 20px; font-size: 14px; color: #666; text-align: center; line-height: 1.6; }
.modal-box .modal-actions { display: flex; border-top: 1px solid #f0f0f0; }
.modal-box .modal-actions button { flex: 1; padding: 14px; font-size: 16px; cursor: pointer; background: none; border: none; }
.modal-box .modal-actions button:first-child { color: #666; border-right: 1px solid #f0f0f0; }
.modal-box .modal-actions button:last-child { color: #1677ff; font-weight: 600; }
/* 按周折叠卡片 */
.day-card { background: #fff; border: 1px solid #e8e8e8; border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
.day-card:last-child { margin-bottom: 0; }
.day-header { display: flex; align-items: center; justify-content: space-between; padding: 12px; cursor: pointer; }
.day-header__day { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.day-header__summary { font-size: 12px; color: #999; }
.day-header__kcal { font-size: 12px; color: #fa8c16; font-weight: 600; }
.day-header .arrow { transition: transform .2s; flex-shrink: 0; }
.day-header .arrow.open { transform: rotate(180deg); }
.day-body { display: none; padding: 0 12px 12px; }
.day-body.open { display: block; }
/* 每餐块 */
.meal-block { background: #fafafa; border-radius: 8px; padding: 10px; margin-bottom: 8px; }
.meal-block:last-child { margin-bottom: 0; }
.meal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.meal-head__name { font-size: 13px; font-weight: 600; color: #1a1a1a; }
.meal-head__subtotal { font-size: 12px; color: #fa8c16; font-weight: 600; }
/* 食物行 */
.food-row { display: flex; align-items: center; gap: 6px; padding: 6px 0; border-bottom: 1px dashed #f0f0f0; }
.food-row:last-child { border-bottom: none; }
.food-row__name { flex: 1; font-size: 13px; color: #333; }
.food-row__input { width: 52px; border: 1px solid #e8e8e8; border-radius: 6px; padding: 4px 6px; font-size: 12px; text-align: center; outline: none; color: #333; background: #fff; }
.food-row__input:focus { border-color: #1677ff; }
.food-row__unit { font-size: 11px; color: #999; }
.food-row__del { width: 20px; height: 20px; border-radius: 50%; border: none; background: #f0f0f0; color: #999; font-size: 12px; cursor: pointer; flex-shrink: 0; line-height: 1; }
/* 添加食物 */
.add-food { display: flex; align-items: center; justify-content: center; gap: 4px; padding: 6px 0; font-size: 12px; color: #1677ff; border: 1px dashed #1677ff; border-radius: 8px; cursor: pointer; margin-top: 8px; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./recipe-list.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">制定食谱</span>
</div>
<div class="scroll-content">
<!-- 基本信息 -->
<div class="form-card">
<div class="form-card__title">基本信息</div>
<div class="form-item">
<div class="form-item__label">食谱名称<span class="req">*</span></div>
<input class="form-input" type="text" placeholder="如:机关减脂周菜单(第 38 周)" />
</div>
<div class="form-item">
<div class="form-item__label">食谱类型<span class="req">*</span></div>
<div class="seg-picker">
<div class="seg-picker__opt active" onclick="segPick(this)">周菜单</div>
<div class="seg-picker__opt" onclick="segPick(this)">季节菜单</div>
</div>
</div>
<div class="form-item">
<div class="form-item__label">发布周期<span class="req">*</span></div>
<div class="date-range">
<input class="form-input" type="text" value="2026-09-21" />
<span class="sep"></span>
<input class="form-input" type="text" value="2026-09-27" />
</div>
</div>
<div class="form-item">
<div class="form-item__label">适用食堂</div>
<div class="seg-picker">
<div class="seg-picker__opt active" onclick="segPick(this)">全部食堂</div>
<div class="seg-picker__opt" onclick="segPick(this)">指定食堂</div>
</div>
</div>
</div>
<!-- 餐次配置(按周 · 每天三餐) -->
<div class="form-card">
<div class="form-card__title">餐次配置(按周 · 每天三餐)</div>
<div id="day-list"></div>
</div>
<!-- 营养汇总 -->
<div class="form-card">
<div class="form-card__title">营养汇总(日均估算)</div>
<div class="nutri-summary">
<div class="nutri-summary__item"><div class="nutri-summary__val">1380</div><div class="nutri-summary__label">热量 kcal</div></div>
<div class="nutri-summary__item"><div class="nutri-summary__val">78</div><div class="nutri-summary__label">蛋白质 g</div></div>
<div class="nutri-summary__item"><div class="nutri-summary__val">32</div><div class="nutri-summary__label">脂肪 g</div></div>
<div class="nutri-summary__item"><div class="nutri-summary__val">188</div><div class="nutri-summary__label">碳水 g</div></div>
</div>
</div>
<div style="height:16px;"></div>
</div>
<!-- 底部操作 -->
<div class="bottom-bar">
<button class="btn-draft" onclick="location.href='./recipe-list.html'">存为草稿</button>
<button class="btn-pub" onclick="openModal('modal-pub')">发布食谱</button>
</div>
<!-- 发布确认弹窗 -->
<div id="modal-pub" class="modal-center">
<div class="modal-box">
<div class="modal-title">发布食谱</div>
<div class="modal-body">发布后该食谱将推送给适用食堂,食堂可引用至食谱排期。确认发布?</div>
<div class="modal-actions">
<button onclick="closeModal('modal-pub')">取消</button>
<button onclick="closeModal('modal-pub');location.href='./recipe-list.html'">确认发布</button>
</div>
</div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* 分段选择 */
function segPick(el) {
el.parentElement.querySelectorAll('.seg-picker__opt').forEach(function(o) { o.classList.remove('active'); });
el.classList.add('active');
}
/* ===== 一周食谱数据(每天三餐,每餐食物含摄入量与热量) ===== */
var WEEK = [
{ day: '周一', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '全麦面包', amount: 80, unit: 'g', kcal: 200 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '清蒸鲈鱼', amount: 150, unit: 'g', kcal: 160 },
{ name: '杂粮饭', amount: 200, unit: 'g', kcal: 240 },
{ name: '蒜蓉西兰花', amount: 150, unit: 'g', kcal: 60 },
{ name: '紫菜蛋花汤', amount: 200, unit: 'ml', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '香煎鸡胸', amount: 120, unit: 'g', kcal: 200 },
{ name: '蔬菜沙拉', amount: 200, unit: 'g', kcal: 80 },
{ name: '小米粥', amount: 200, unit: 'g', kcal: 120 }
]}
]},
{ day: '周二', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '燕麦牛奶', amount: 300, unit: 'ml', kcal: 220 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '白灼虾', amount: 150, unit: 'g', kcal: 140 },
{ name: '糙米饭', amount: 200, unit: 'g', kcal: 230 },
{ name: '清炒时蔬', amount: 150, unit: 'g', kcal: 55 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '蔬菜豆腐汤', amount: 300, unit: 'g', kcal: 150 },
{ name: '杂粮馒头', amount: 100, unit: 'g', kcal: 220 }
]}
]},
{ day: '周三', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '豆浆', amount: 250, unit: 'ml', kcal: 80 },
{ name: '蒸红薯', amount: 100, unit: 'g', kcal: 90 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '卤牛肉', amount: 100, unit: 'g', kcal: 160 },
{ name: '荞麦面', amount: 200, unit: 'g', kcal: 230 },
{ name: '凉拌黄瓜', amount: 150, unit: 'g', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '清炒时蔬', amount: 200, unit: 'g', kcal: 60 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '菌菇汤', amount: 200, unit: 'g', kcal: 50 }
]}
]},
{ day: '周四', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '杂粮粥', amount: 300, unit: 'g', kcal: 200 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '香煎鸡胸', amount: 150, unit: 'g', kcal: 250 },
{ name: '藜麦饭', amount: 150, unit: 'g', kcal: 180 },
{ name: '西兰花', amount: 150, unit: 'g', kcal: 60 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '虾仁沙拉', amount: 200, unit: 'g', kcal: 150 },
{ name: '全麦面包', amount: 50, unit: 'g', kcal: 120 }
]}
]},
{ day: '周五', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '全麦面包', amount: 80, unit: 'g', kcal: 200 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 },
{ name: '香蕉', amount: 100, unit: 'g', kcal: 90 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '清蒸鱼', amount: 150, unit: 'g', kcal: 160 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '凉拌木耳', amount: 100, unit: 'g', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '菌菇汤', amount: 300, unit: 'g', kcal: 120 },
{ name: '杂粮饭', amount: 150, unit: 'g', kcal: 180 }
]}
]},
{ day: '周六', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '燕麦', amount: 50, unit: 'g', kcal: 190 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '白灼虾', amount: 150, unit: 'g', kcal: 140 },
{ name: '杂粮饭', amount: 200, unit: 'g', kcal: 240 },
{ name: '蔬菜沙拉', amount: 150, unit: 'g', kcal: 60 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '蔬菜沙拉', amount: 200, unit: 'g', kcal: 80 },
{ name: '鸡胸肉', amount: 100, unit: 'g', kcal: 170 },
{ name: '玉米', amount: 100, unit: 'g', kcal: 110 }
]}
]},
{ day: '周日', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '豆浆', amount: 250, unit: 'ml', kcal: 80 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '卤牛肉', amount: 100, unit: 'g', kcal: 160 },
{ name: '糙米饭', amount: 200, unit: 'g', kcal: 230 },
{ name: '清炒时蔬', amount: 150, unit: 'g', kcal: 55 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '鸡胸沙拉', amount: 250, unit: 'g', kcal: 200 },
{ name: '小米粥', amount: 200, unit: 'g', kcal: 120 }
]}
]}
];
/* 计算某餐总热量 */
function mealSubtotal(di, mi) {
return WEEK[di].meals[mi].foods.reduce(function(s, f) { return s + (parseInt(f.kcal) || 0); }, 0);
}
/* 计算某天总热量 */
function dayTotal(di) {
return WEEK[di].meals.reduce(function(s, m, mi) { return s + mealSubtotal(di, mi); }, 0);
}
/* 某天三餐小计摘要 */
function daySummary(di) {
return WEEK[di].meals.map(function(m, mi) { return m.name.charAt(0) + mealSubtotal(di, mi); }).join(' · ');
}
/* 渲染单个食物行 */
function renderFood(di, mi, fi) {
var f = WEEK[di].meals[mi].foods[fi];
return '<div class="food-row">' +
'<span class="food-row__name">' + f.name + '</span>' +
'<input class="food-row__input" type="text" value="' + f.amount + '" oninput="updateAmount(' + di + ',' + mi + ',' + fi + ',this)" />' +
'<span class="food-row__unit">' + f.unit + '</span>' +
'<input class="food-row__input" type="text" value="' + f.kcal + '" oninput="updateKcal(' + di + ',' + mi + ',' + fi + ',this)" />' +
'<span class="food-row__unit">kcal</span>' +
'<button class="food-row__del" onclick="removeFood(' + di + ',' + mi + ',' + fi + ')">×</button>' +
'</div>';
}
/* 渲染某餐块 */
function renderMeal(di, mi) {
var m = WEEK[di].meals[mi];
var html = '<div class="meal-block">' +
'<div class="meal-head"><span class="meal-head__name">' + m.icon + ' ' + m.name + '</span><span class="meal-head__subtotal" id="meal-sub-' + di + '-' + mi + '">小计 ' + mealSubtotal(di, mi) + ' kcal</span></div>';
m.foods.forEach(function(f, fi) { html += renderFood(di, mi, fi); });
html += '<div class="add-food" onclick="addFood(' + di + ',' + mi + ')"> 添加食物</div></div>';
return html;
}
/* 渲染整周折叠卡片 */
function renderDayList() {
var html = '';
WEEK.forEach(function(day, di) {
html += '<div class="day-card">' +
'<div class="day-header" onclick="toggleDay(' + di + ')">' +
'<span class="day-header__day">' + day.day + '</span>' +
'<span class="day-header__summary">' + daySummary(di) + '</span>' +
'<span class="day-header__kcal" id="day-kcal-' + di + '">' + dayTotal(di) + ' kcal</span>' +
'<svg class="arrow" id="arrow-' + di + '" width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="#999" stroke-width="2"><path d="M4 6l4 4 4-4"/></svg>' +
'</div>' +
'<div class="day-body" id="day-body-' + di + '">' +
day.meals.map(function(m, mi) { return renderMeal(di, mi); }).join('') +
'</div>' +
'</div>';
});
document.getElementById('day-list').innerHTML = html;
/* 默认展开周一 */
document.getElementById('day-body-0').classList.add('open');
document.getElementById('arrow-0').classList.add('open');
}
/* 折叠/展开某天 */
function toggleDay(di) {
var body = document.getElementById('day-body-' + di);
var arrow = document.getElementById('arrow-' + di);
body.classList.toggle('open');
arrow.classList.toggle('open');
}
/* 更新摄入量 */
function updateAmount(di, mi, fi, el) {
WEEK[di].meals[mi].foods[fi].amount = el.value;
}
/* 更新热量并重算小计与总计 */
function updateKcal(di, mi, fi, el) {
WEEK[di].meals[mi].foods[fi].kcal = parseInt(el.value) || 0;
document.getElementById('meal-sub-' + di + '-' + mi).textContent = '小计 ' + mealSubtotal(di, mi) + ' kcal';
document.getElementById('day-kcal-' + di).textContent = dayTotal(di) + ' kcal';
}
/* 添加食物 */
function addFood(di, mi) {
WEEK[di].meals[mi].foods.push({ name: '新食物', amount: 100, unit: 'g', kcal: 100 });
var body = document.getElementById('day-body-' + di);
body.innerHTML = WEEK[di].meals.map(function(m, mi2) { return renderMeal(di, mi2); }).join('');
}
/* 删除食物 */
function removeFood(di, mi, fi) {
WEEK[di].meals[mi].foods.splice(fi, 1);
var body = document.getElementById('day-body-' + di);
body.innerHTML = WEEK[di].meals.map(function(m, mi2) { return renderMeal(di, mi2); }).join('');
document.getElementById('day-kcal-' + di).textContent = dayTotal(di) + ' kcal';
}
/* 初始化渲染 */
renderDayList();
function openModal(id) { var m = document.getElementById(id); if (m) m.classList.add('active'); }
function closeModal(id) { var m = document.getElementById(id); if (m) m.classList.remove('active'); }
</script>
</body>
</html>
@@ -0,0 +1,309 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 食谱详情 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
/* 头部 */
.recipe-header { background: linear-gradient(135deg,#1677ff,#0958d9); padding: 16px 20px; color: #fff; }
.recipe-header__name { font-size: 18px; font-weight: 700; }
.recipe-header__meta { font-size: 12px; color: rgba(255,255,255,0.85); margin-top: 6px; }
.recipe-header__tags { display: flex; gap: 6px; margin-top: 10px; flex-wrap: wrap; }
.recipe-header__tag { font-size: 11px; padding: 3px 10px; border-radius: 12px; background: rgba(255,255,255,0.2); }
/* 卡片 */
.card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
.card__title { font-size: 14px; font-weight: 700; color: #1a1a1a; margin-bottom: 10px; }
/* 引用统计 */
.cite-stat { display: flex; gap: 8px; }
.cite-stat__item { flex: 1; text-align: center; background: #fafafa; border-radius: 8px; padding: 10px 0; }
.cite-stat__val { font-size: 16px; font-weight: 700; color: #1677ff; }
.cite-stat__label { font-size: 11px; color: #999; margin-top: 2px; }
/* 食堂引用列表 */
.canteen-item { display: flex; align-items: center; gap: 10px; padding: 12px 0; border-bottom: 1px solid #f5f5f5; }
.canteen-item:last-child { border-bottom: none; }
.canteen-item__icon { width: 40px; height: 40px; border-radius: 10px; display: flex; align-items: center; justify-content: center; font-size: 20px; flex-shrink: 0; }
.canteen-item__info { flex: 1; min-width: 0; }
.canteen-item__name { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.canteen-item__meta { font-size: 12px; color: #999; margin-top: 2px; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-green { background: #f6ffed; color: #52c41a; }
.tag-orange { background: #fff7e6; color: #fa8c16; }
/* 一周餐次安排(按天折叠,每天三餐,食物含摄入量与热量) */
.day-card { background: #fff; border: 1px solid #e8e8e8; border-radius: 10px; margin-bottom: 10px; overflow: hidden; }
.day-card:last-child { margin-bottom: 0; }
.day-header { display: flex; align-items: center; justify-content: space-between; padding: 12px; cursor: pointer; }
.day-header__day { font-size: 14px; font-weight: 600; color: #1a1a1a; }
.day-header__summary { font-size: 12px; color: #999; }
.day-header__kcal { font-size: 12px; color: #fa8c16; font-weight: 600; }
.day-header .arrow { transition: transform .2s; flex-shrink: 0; }
.day-header .arrow.open { transform: rotate(180deg); }
.day-body { display: none; padding: 0 12px 12px; }
.day-body.open { display: block; }
.meal-block { background: #fafafa; border-radius: 8px; padding: 10px; margin-bottom: 8px; }
.meal-block:last-child { margin-bottom: 0; }
.meal-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 6px; }
.meal-head__name { font-size: 13px; font-weight: 600; color: #1a1a1a; }
.meal-head__subtotal { font-size: 12px; color: #fa8c16; font-weight: 600; }
.food-row { display: flex; align-items: center; gap: 6px; padding: 6px 0; border-bottom: 1px dashed #f0f0f0; }
.food-row:last-child { border-bottom: none; }
.food-row__name { flex: 1; font-size: 13px; color: #333; }
.food-row__amount { font-size: 12px; color: #666; width: 44px; text-align: right; flex-shrink: 0; }
.food-row__kcal { font-size: 12px; color: #fa8c16; font-weight: 600; width: 56px; text-align: right; flex-shrink: 0; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./recipe-list.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">食谱详情</span>
</div>
<div class="scroll-content">
<!-- 头部 -->
<div class="recipe-header">
<div class="recipe-header__name">机关减脂周菜单(第 37 周)</div>
<div class="recipe-header__meta">周菜单 · 2026-09-14 至 09-20 · 李营养师</div>
<div class="recipe-header__tags">
<span class="recipe-header__tag">低脂</span>
<span class="recipe-header__tag">均衡营养</span>
<span class="recipe-header__tag">已发布</span>
</div>
</div>
<!-- 引用情况 -->
<div class="card">
<div class="card__title">引用情况</div>
<div class="cite-stat">
<div class="cite-stat__item"><div class="cite-stat__val">5</div><div class="cite-stat__label">已引用食堂</div></div>
<div class="cite-stat__item"><div class="cite-stat__val">3</div><div class="cite-stat__label">待确认</div></div>
<div class="cite-stat__item"><div class="cite-stat__val">0</div><div class="cite-stat__label">已拒绝</div></div>
</div>
<div style="margin-top:12px;">
<div class="canteen-item">
<div class="canteen-item__icon" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">🏢</div>
<div class="canteen-item__info"><div class="canteen-item__name">机关食堂</div><div class="canteen-item__meta">公司机关 · 已排期</div></div>
<span class="tag tag-green">已引用</span>
</div>
<div class="canteen-item">
<div class="canteen-item__icon" style="background:linear-gradient(135deg,#e6f4ff,#bdd7ff);">🏭</div>
<div class="canteen-item__info"><div class="canteen-item__name">采油一厂食堂</div><div class="canteen-item__meta">采油一厂 · 已排期</div></div>
<span class="tag tag-green">已引用</span>
</div>
<div class="canteen-item">
<div class="canteen-item__icon" style="background:linear-gradient(135deg,#fff7e6,#ffd591);">🏪</div>
<div class="canteen-item__info"><div class="canteen-item__name">信息中心食堂</div><div class="canteen-item__meta">信息技术中心 · 待确认</div></div>
<span class="tag tag-orange">待确认</span>
</div>
</div>
</div>
<!-- 一周餐次安排 -->
<div class="card">
<div class="card__title">一周餐次安排</div>
<div id="day-list"></div>
</div>
<div style="height:16px;"></div>
</div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
/* ===== 一周食谱数据(每天三餐,每餐食物含摄入量与热量) ===== */
var WEEK = [
{ day: '周一', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '全麦面包', amount: 80, unit: 'g', kcal: 200 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '清蒸鲈鱼', amount: 150, unit: 'g', kcal: 160 },
{ name: '杂粮饭', amount: 200, unit: 'g', kcal: 240 },
{ name: '蒜蓉西兰花', amount: 150, unit: 'g', kcal: 60 },
{ name: '紫菜蛋花汤', amount: 200, unit: 'ml', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '香煎鸡胸', amount: 120, unit: 'g', kcal: 200 },
{ name: '蔬菜沙拉', amount: 200, unit: 'g', kcal: 80 },
{ name: '小米粥', amount: 200, unit: 'g', kcal: 120 }
]}
]},
{ day: '周二', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '燕麦牛奶', amount: 300, unit: 'ml', kcal: 220 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '白灼虾', amount: 150, unit: 'g', kcal: 140 },
{ name: '糙米饭', amount: 200, unit: 'g', kcal: 230 },
{ name: '清炒时蔬', amount: 150, unit: 'g', kcal: 55 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '蔬菜豆腐汤', amount: 300, unit: 'g', kcal: 150 },
{ name: '杂粮馒头', amount: 100, unit: 'g', kcal: 220 }
]}
]},
{ day: '周三', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '豆浆', amount: 250, unit: 'ml', kcal: 80 },
{ name: '蒸红薯', amount: 100, unit: 'g', kcal: 90 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '卤牛肉', amount: 100, unit: 'g', kcal: 160 },
{ name: '荞麦面', amount: 200, unit: 'g', kcal: 230 },
{ name: '凉拌黄瓜', amount: 150, unit: 'g', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '清炒时蔬', amount: 200, unit: 'g', kcal: 60 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '菌菇汤', amount: 200, unit: 'g', kcal: 50 }
]}
]},
{ day: '周四', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '杂粮粥', amount: 300, unit: 'g', kcal: 200 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '香煎鸡胸', amount: 150, unit: 'g', kcal: 250 },
{ name: '藜麦饭', amount: 150, unit: 'g', kcal: 180 },
{ name: '西兰花', amount: 150, unit: 'g', kcal: 60 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '虾仁沙拉', amount: 200, unit: 'g', kcal: 150 },
{ name: '全麦面包', amount: 50, unit: 'g', kcal: 120 }
]}
]},
{ day: '周五', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '全麦面包', amount: 80, unit: 'g', kcal: 200 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 },
{ name: '香蕉', amount: 100, unit: 'g', kcal: 90 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '清蒸鱼', amount: 150, unit: 'g', kcal: 160 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '凉拌木耳', amount: 100, unit: 'g', kcal: 40 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '菌菇汤', amount: 300, unit: 'g', kcal: 120 },
{ name: '杂粮饭', amount: 150, unit: 'g', kcal: 180 }
]}
]},
{ day: '周六', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 },
{ name: '燕麦', amount: 50, unit: 'g', kcal: 190 },
{ name: '牛奶', amount: 250, unit: 'ml', kcal: 65 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '白灼虾', amount: 150, unit: 'g', kcal: 140 },
{ name: '杂粮饭', amount: 200, unit: 'g', kcal: 240 },
{ name: '蔬菜沙拉', amount: 150, unit: 'g', kcal: 60 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '蔬菜沙拉', amount: 200, unit: 'g', kcal: 80 },
{ name: '鸡胸肉', amount: 100, unit: 'g', kcal: 170 },
{ name: '玉米', amount: 100, unit: 'g', kcal: 110 }
]}
]},
{ day: '周日', meals: [
{ icon: '🥣', name: '早餐', foods: [
{ name: '豆浆', amount: 250, unit: 'ml', kcal: 80 },
{ name: '玉米', amount: 150, unit: 'g', kcal: 160 },
{ name: '水煮蛋', amount: 60, unit: 'g', kcal: 70 }
]},
{ icon: '🍱', name: '午餐', foods: [
{ name: '卤牛肉', amount: 100, unit: 'g', kcal: 160 },
{ name: '糙米饭', amount: 200, unit: 'g', kcal: 230 },
{ name: '清炒时蔬', amount: 150, unit: 'g', kcal: 55 }
]},
{ icon: '🍽️', name: '晚餐', foods: [
{ name: '鸡胸沙拉', amount: 250, unit: 'g', kcal: 200 },
{ name: '小米粥', amount: 200, unit: 'g', kcal: 120 }
]}
]}
];
/* 计算某餐总热量 */
function mealSubtotal(di, mi) {
return WEEK[di].meals[mi].foods.reduce(function(s, f) { return s + f.kcal; }, 0);
}
/* 计算某天总热量 */
function dayTotal(di) {
return WEEK[di].meals.reduce(function(s, m, mi) { return s + mealSubtotal(di, mi); }, 0);
}
/* 某天三餐小计摘要 */
function daySummary(di) {
return WEEK[di].meals.map(function(m, mi) { return m.name.charAt(0) + mealSubtotal(di, mi); }).join(' · ');
}
/* 渲染整周折叠卡片(只读) */
function renderDayList() {
var html = '';
WEEK.forEach(function(day, di) {
html += '<div class="day-card">' +
'<div class="day-header" onclick="toggleDay(' + di + ')">' +
'<span class="day-header__day">' + day.day + '</span>' +
'<span class="day-header__summary">' + daySummary(di) + '</span>' +
'<span class="day-header__kcal">' + dayTotal(di) + ' kcal</span>' +
'<svg class="arrow" id="arrow-' + di + '" width="14" height="14" viewBox="0 0 16 16" fill="none" stroke="#999" stroke-width="2"><path d="M4 6l4 4 4-4"/></svg>' +
'</div>' +
'<div class="day-body" id="day-body-' + di + '">' +
day.meals.map(function(m, mi) {
return '<div class="meal-block">' +
'<div class="meal-head"><span class="meal-head__name">' + m.icon + ' ' + m.name + '</span><span class="meal-head__subtotal">小计 ' + mealSubtotal(di, mi) + ' kcal</span></div>' +
m.foods.map(function(f) {
return '<div class="food-row"><span class="food-row__name">' + f.name + '</span><span class="food-row__amount">' + f.amount + f.unit + '</span><span class="food-row__kcal">' + f.kcal + ' kcal</span></div>';
}).join('') +
'</div>';
}).join('') +
'</div>' +
'</div>';
});
document.getElementById('day-list').innerHTML = html;
/* 默认展开周一 */
document.getElementById('day-body-0').classList.add('open');
document.getElementById('arrow-0').classList.add('open');
}
/* 折叠/展开某天 */
function toggleDay(di) {
var body = document.getElementById('day-body-' + di);
var arrow = document.getElementById('arrow-' + di);
body.classList.toggle('open');
arrow.classList.toggle('open');
}
/* 初始化渲染 */
renderDayList();
</script>
</body>
</html>
@@ -0,0 +1,175 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>营养师工作台 - 我的食谱 | 健康CQ原型</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #f0f2f5; display: flex; justify-content: center; align-items: flex-start; min-height: 100vh; padding: 20px; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif; }
.phone-shell { width: 390px; height: 844px; background: #f7f8fa; border-radius: 44px; box-shadow: 0 20px 60px rgba(0,0,0,0.25), inset 0 0 0 2px #e0e0e0; overflow: hidden; position: relative; display: flex; flex-direction: column; flex-shrink: 0; }
.status-bar { height: 44px; background: #fff; display: flex; align-items: center; justify-content: space-between; padding: 0 24px; flex-shrink: 0; z-index: 10; }
.status-bar .time { font-size: 15px; font-weight: 700; color: #1a1a1a; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; font-size: 12px; color: #1a1a1a; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; flex-shrink: 0; border-bottom: 1px solid #f0f0f0; position: relative; }
.nav-back { display: flex; align-items: center; gap: 4px; color: #1677ff; font-size: 15px; cursor: pointer; background: none; border: none; padding: 4px 0; }
.nav-title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; color: #1a1a1a; white-space: nowrap; }
.nav-add { margin-left: auto; color: #1677ff; font-size: 14px; cursor: pointer; background: none; border: none; font-weight: 600; }
.scroll-content { flex: 1; overflow-y: auto; background: #f7f8fa; }
.scroll-content::-webkit-scrollbar { display: none; }
.seg-tabs { display: flex; background: #fff; border-bottom: 1px solid #f0f0f0; flex-shrink: 0; }
.seg-tab { flex: 1; text-align: center; padding: 12px 0; font-size: 14px; color: #666; cursor: pointer; border-bottom: 2px solid transparent; }
.seg-tab.active { color: #1677ff; border-bottom-color: #1677ff; font-weight: 600; }
.seg-tab .badge { display: inline-block; background: #e8e8e8; color: #666; font-size: 10px; font-weight: 700; min-width: 16px; height: 16px; border-radius: 8px; padding: 0 4px; margin-left: 4px; vertical-align: middle; line-height: 16px; }
.seg-tab.active .badge { background: #e6f4ff; color: #1677ff; }
/* 食谱卡片 */
.recipe-card { background: #fff; border-radius: 12px; margin: 10px 12px 0; padding: 14px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); cursor: pointer; }
.recipe-card:active { transform: scale(0.98); }
.recipe-card__head { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.recipe-card__icon { width: 44px; height: 44px; border-radius: 12px; display: flex; align-items: center; justify-content: center; font-size: 22px; flex-shrink: 0; }
.recipe-card__info { flex: 1; min-width: 0; }
.recipe-card__name { font-size: 15px; font-weight: 600; color: #1a1a1a; }
.recipe-card__meta { font-size: 12px; color: #999; margin-top: 2px; }
.recipe-card__footer { display: flex; align-items: center; justify-content: space-between; padding-top: 10px; border-top: 1px solid #f5f5f5; }
.recipe-card__cite { font-size: 12px; color: #666; }
.recipe-card__cite .num { font-weight: 700; color: #1677ff; }
.tag { display: inline-block; padding: 2px 8px; border-radius: 4px; font-size: 11px; font-weight: 600; }
.tag-green { background: #f6ffed; color: #52c41a; }
.tag-gray { background: #f5f5f5; color: #999; }
.tag-blue { background: #e6f4ff; color: #1677ff; }
/* 制定食谱按钮 */
.fab { position: absolute; right: 20px; bottom: 100px; width: 56px; height: 56px; border-radius: 50%; background: #1677ff; color: #fff; display: flex; align-items: center; justify-content: center; font-size: 28px; cursor: pointer; box-shadow: 0 4px 12px rgba(22,119,255,0.4); z-index: 50; }
.fab:active { transform: scale(0.94); }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">9:41</span>
<div class="icons"><span>●●●</span><span>WiFi</span><span>🔋</span></div>
</div>
<!-- 导航栏 -->
<div class="nav-bar">
<button class="nav-back" onclick="location.href='./index.html'">
<svg width="10" height="16" viewBox="0 0 10 16" fill="none" stroke="currentColor" stroke-width="2"><path d="M8 1L2 8l6 7"/></svg>返回
</button>
<span class="nav-title">我的食谱</span>
<!-- [交互] 点击跳转至: ./recipe-create.html -->
<button class="nav-add" onclick="location.href='./recipe-create.html'">制定食谱</button>
</div>
<!-- Tab -->
<div class="seg-tabs">
<div class="seg-tab active" onclick="switchTab(this,'panel-all')">全部<span class="badge">6</span></div>
<div class="seg-tab" onclick="switchTab(this,'panel-pub')">已发布<span class="badge">4</span></div>
<div class="seg-tab" onclick="switchTab(this,'panel-draft')">草稿<span class="badge">2</span></div>
</div>
<div class="scroll-content">
<div id="panel-all">
<!-- [交互] 点击跳转至: ./recipe-detail.html -->
<div class="recipe-card" onclick="location.href='./recipe-detail.html'">
<div class="recipe-card__head">
<div class="recipe-card__icon" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">🥗</div>
<div class="recipe-card__info">
<div class="recipe-card__name">机关减脂周菜单(第 37 周)</div>
<div class="recipe-card__meta">周菜单 · 早/中/晚 · 2026-09-14 ~ 09-20</div>
</div>
<span class="tag tag-green">已发布</span>
</div>
<div class="recipe-card__footer">
<span class="recipe-card__cite"><span class="num">5</span> 个食堂引用</span>
<span style="font-size:12px;color:#1677ff;">查看详情 </span>
</div>
</div>
<div class="recipe-card" onclick="location.href='./recipe-detail.html'">
<div class="recipe-card__head">
<div class="recipe-card__icon" style="background:linear-gradient(135deg,#fff7e6,#ffd591);">🍚</div>
<div class="recipe-card__info">
<div class="recipe-card__name">一线高能量周菜单(第 37 周)</div>
<div class="recipe-card__meta">周菜单 · 早/中/晚 · 2026-09-14 ~ 09-20</div>
</div>
<span class="tag tag-green">已发布</span>
</div>
<div class="recipe-card__footer">
<span class="recipe-card__cite"><span class="num">3</span> 个食堂引用</span>
<span style="font-size:12px;color:#1677ff;">查看详情 </span>
</div>
</div>
<div class="recipe-card" onclick="location.href='./recipe-detail.html'">
<div class="recipe-card__head">
<div class="recipe-card__icon" style="background:linear-gradient(135deg,#e6f4ff,#bdd7ff);">🍂</div>
<div class="recipe-card__info">
<div class="recipe-card__name">秋季养生季节菜单</div>
<div class="recipe-card__meta">季节菜单 · 早/中/晚 · 2026-09 ~ 11</div>
</div>
<span class="tag tag-green">已发布</span>
</div>
<div class="recipe-card__footer">
<span class="recipe-card__cite"><span class="num">8</span> 个食堂引用</span>
<span style="font-size:12px;color:#1677ff;">查看详情 </span>
</div>
</div>
<div class="recipe-card" onclick="location.href='./recipe-detail.html'">
<div class="recipe-card__head">
<div class="recipe-card__icon" style="background:linear-gradient(135deg,#f9f0ff,#d3adf7);">🥩</div>
<div class="recipe-card__info">
<div class="recipe-card__name">控糖低 GI 周菜单(第 38 周)</div>
<div class="recipe-card__meta">周菜单 · 早/中/晚 · 2026-09-21 ~ 09-27</div>
</div>
<span class="tag tag-gray">草稿</span>
</div>
<div class="recipe-card__footer">
<span class="recipe-card__cite">尚未发布</span>
<span style="font-size:12px;color:#1677ff;">继续编辑 </span>
</div>
</div>
<div style="height:90px;"></div>
</div>
<div id="panel-pub" style="display:none;">
<div class="recipe-card" onclick="location.href='./recipe-detail.html'">
<div class="recipe-card__head">
<div class="recipe-card__icon" style="background:linear-gradient(135deg,#f6ffed,#b7eb8f);">🥗</div>
<div class="recipe-card__info"><div class="recipe-card__name">机关减脂周菜单(第 37 周)</div><div class="recipe-card__meta">周菜单 · 2026-09-14 ~ 09-20</div></div>
<span class="tag tag-green">已发布</span>
</div>
<div class="recipe-card__footer"><span class="recipe-card__cite"><span class="num">5</span> 个食堂引用</span><span style="font-size:12px;color:#1677ff;">查看详情 </span></div>
</div>
<div style="height:90px;"></div>
</div>
<div id="panel-draft" style="display:none;">
<div class="recipe-card" onclick="location.href='./recipe-detail.html'">
<div class="recipe-card__head">
<div class="recipe-card__icon" style="background:linear-gradient(135deg,#f9f0ff,#d3adf7);">🥩</div>
<div class="recipe-card__info"><div class="recipe-card__name">控糖低 GI 周菜单(第 38 周)</div><div class="recipe-card__meta">周菜单 · 2026-09-21 ~ 09-27</div></div>
<span class="tag tag-gray">草稿</span>
</div>
<div class="recipe-card__footer"><span class="recipe-card__cite">尚未发布</span><span style="font-size:12px;color:#1677ff;">继续编辑 </span></div>
</div>
<div style="height:90px;"></div>
</div>
</div>
<!-- 制定食谱悬浮按钮 -->
<div class="fab" onclick="location.href='./recipe-create.html'"></div>
</div>
<script>
/* 标记当前角色为营养师 */
sessionStorage.setItem('appRole', 'nutritionist');
function switchTab(el, panelId) {
el.closest('.seg-tabs').querySelectorAll('.seg-tab').forEach(function(t) { t.classList.remove('active'); });
el.classList.add('active');
['panel-all','panel-pub','panel-draft'].forEach(function(id) {
document.getElementById(id).style.display = id === panelId ? 'block' : 'none';
});
}
</script>
</body>
</html>
+16 -10
View File
@@ -2,7 +2,7 @@
## 项目概述
本项目以 HTML 方式生成「健康CQ升级」平台的高保真交互原型,覆盖 Web 管理端、员工端 APP、健康应急 APP 三大终端,用于需求确认、交互评审及后续导入墨刀进行团队协作。
本项目以 HTML 方式生成「健康CQ升级」平台的高保真交互原型,覆盖 Web 管理端、员工端 APP、健康服务 APP 三大终端,用于需求确认、交互评审及后续导入墨刀进行团队协作。
---
@@ -15,7 +15,7 @@ prototype-user-app/
├── index.html # 全局导航页(项目入口)
├── web-admin/ # Web 管理端原型
├── employee-app/ # 员工端 APP 原型
├── emergency-app/ # 健康应急 APP 原型
├── emergency-app/ # 健康服务 APP 原型
├── other-terminals/ # 其他终端原型(小程序、大屏、PAD、餐厅的终端设备)
├── 项目背景.md # 本文件 - 项目约束与规范
└── README.md # 项目说明
@@ -25,7 +25,7 @@ prototype-user-app/
根目录 `index.html` 作为项目统一入口,部署到服务器后供研发人员浏览所有原型页面。
- 通过 Tab 切换四大板块(Web 管理端 / 员工端 APP / 健康应急 APP / 其他终端)
- 通过 Tab 切换四大板块(Web 管理端 / 员工端 APP / 健康服务 APP / 其他终端)
- 以模块卡片展示各业务模块,点击卡片跳转至该模块主页(index.html)
- 点击卡片右上角页数徽章,悬浮展示该模块所有页面和弹窗的跳转链接
- 已有原型的模块卡片带绿色边框呼吸灯动画,待开发模块为虚线灰色卡片
@@ -77,10 +77,10 @@ web-admin/
└── frontline-medical/ # 一线医疗
```
**健康应急 APPemergency-app/**
**健康服务 APPemergency-app/**
底部固定 5 个 Tab:工作台、知识库、AI助手、消息(即时通讯)、我的。
6 种角色登录后看到的工作台、知识库、我的内容不同,AI助手和消息全角色共享。
7 种角色登录后看到的工作台、知识库、我的内容不同,AI助手和消息全角色共享。
| 角色 | 英文标识 | 说明 |
|------|---------|------|
@@ -89,6 +89,7 @@ web-admin/
| 应急专业人员 | professional | 参与应急响应的专业技术人员 |
| 应急驻场人员 | onsite | 驻扎在现场的应急保障人员 |
| 咨询小助手 | assistant | 辅助答疑、常见问题推送、数据统计 |
| 营养师 | nutritionist | 营养健康服务提供者,承接员工营养咨询、制定营养方案与食谱 |
| 管理员 | admin | 应急APP端的管理与配置人员 |
目录按角色优先组织,每个角色包含自己的工作台、知识库、我的页面:
@@ -119,6 +120,10 @@ emergency-app/
│ ├── workbench/
│ ├── knowledge/
│ └── profile/
├── nutritionist/ # 营养师
│ ├── workbench/
│ ├── knowledge/
│ └── profile/
├── ai-assistant/ # AI助手(全角色共享)
│ └── index.html
@@ -444,8 +449,9 @@ window.location.href = '../health-consult/consult-list.html';
|---------|---------|-----------|
| 能源员工 | CQ能源一线员工及管理人员 | 员工端 APP |
| 平台管理员 | 健康管理部门后台运营人员 | Web 管理端 |
| 健康咨询专家 | 专业医师/健康管理师 | 健康应急 APP |
| 应急就医服务人员 | 应急调度与协调人员 | 健康应急 APP |
| 健康咨询专家 | 专业医师/健康管理师 | 健康服务 APP |
| 应急就医服务人员 | 应急调度与协调人员 | 健康服务 APP |
| 营养师 | 制定营养方案与食谱、提供员工营养咨询服务 | 健康服务 APP |
| 营养管理用户 | 通过小程序进行营养管理的员工 | 微信小程序 |
| 体检医生 | 负责体检检查的医生 | 体检医生工作台 |
| 医疗点医护人员 | 一线医疗点驻点医护 | 医疗点PAD端 |
@@ -458,7 +464,7 @@ window.location.href = '../health-consult/consult-list.html';
| 系统管理 | 用户管理、角色权限、组织架构、系统配置 | Web 管理端 |
| 健康体检 | 体检预约、报告管理、历年数据对比 | 员工端 APP / Web 管理端 |
| 体重管理 | 体重记录、目标设定、进度追踪 | 员工端 APP / Web 管理端 |
| 营养管理 | 用餐记录、膳食指导、营养分析 | 员工端 APP / Web 管理端 |
| 营养管理 | 用餐记录、膳食指导、营养分析 | 员工端 APP / Web 管理端 / 健康服务 APP |
| 运动管理 | 运动数据记录、目标设定、运动计划 | 员工端 APP / Web 管理端 |
| 健康监测 | 智能手表采集心率、血压、血氧、睡眠数据 | 员工端 APP / Web 管理端 |
| 健康评估 | 健康风险评估报告,识别风险等级 | 员工端 APP / Web 管理端 |
@@ -468,8 +474,8 @@ window.location.href = '../health-consult/consult-list.html';
| 心脑血管病预防 | 心脑血管疾病风险筛查与预防管理 | 员工端 APP / Web 管理端 |
| 糖尿病预防 | 糖尿病风险筛查与预防管理 | 员工端 APP / Web 管理端 |
| 癌症预防 | 癌症风险筛查与预防管理 | 员工端 APP / Web 管理端 |
| 健康咨询/专家咨询 | 在线健康咨询,支持图文与视频咨询 | 员工端 APP / 健康应急 APP / Web 管理端 |
| 应急就医 | 应急申请、资源调度、进度跟踪的全流程管理 | 员工端 APP / 健康应急 APP / Web 管理端 |
| 健康咨询/专家咨询 | 在线健康咨询,支持图文与视频咨询 | 员工端 APP / 健康服务 APP / Web 管理端 |
| 应急就医 | 应急申请、资源调度、进度跟踪的全流程管理 | 员工端 APP / 健康服务 APP / Web 管理端 |
| 一线医疗 | 一线医疗点服务与管理 | 员工端 APP / Web 管理端 |
| AI | 智能健康助手,AI问答与健康建议 | 员工端 APP |
| 营养管理小程序 | 员工端营养管理微信小程序 | 微信小程序 |