feat: 营养管理小程序原型页面调整(小程序购买净菜包+健康档案)
This commit is contained in:
BIN
Binary file not shown.
|
Before Width: | Height: | Size: 38 KiB |
@@ -1,224 +0,0 @@
|
||||
const fs=require('fs'),f='other-module/emergency-screen/xian-center/index-v3.html';
|
||||
let d=fs.readFileSync(f,'utf8');
|
||||
const ok=(s,desc)=>{if(!s){console.log('FAIL: '+desc);process.exit(1);}console.log('OK: '+desc);};
|
||||
|
||||
// ═══ CSS changes (no Chinese text needed) ═══
|
||||
d=d.replace('grid-template-columns:1fr 1fr;gap:10px;','grid-template-columns:1fr 1fr 1fr;gap:8px;');
|
||||
d=d.replace('.stat-card{background:rgba(24,144,255,0.06);border:1px solid var(--panel-border);border-radius:8px;\r\n padding:12px;text-align:center;transition:all .2s;cursor:pointer;}',
|
||||
'.stat-card{display:flex;flex-direction:column;justify-content:center;align-items:center;gap:3px;\r\n padding:10px 6px;min-height:66px;text-align:center;position:relative;overflow:hidden;cursor:pointer;\r\n background:linear-gradient(135deg,rgba(24,144,255,0.10),rgba(10,30,60,0.45));\r\n border:1px solid var(--panel-border);border-radius:8px;transition:all .25s;}\r\n .stat-card::before{content:\"\";position:absolute;left:0;top:20%;bottom:20%;width:3px;\r\n background:var(--primary);border-radius:0 2px 2px 0;box-shadow:0 0 8px rgba(24,144,255,0.55);}\r\n .stat-card::after{content:\"\";position:absolute;inset:0;pointer-events:none;\r\n background:radial-gradient(ellipse at 100% 0%,rgba(24,144,255,0.06),transparent 55%);}');
|
||||
d=d.replace('.stat-card:hover{border-color:rgba(24,144,255,0.35);box-shadow:0 0 12px rgba(24,144,255,0.1);}',
|
||||
'.stat-card:hover{border-color:rgba(24,144,255,0.45);box-shadow:0 0 16px rgba(24,144,255,0.15);\r\n transform:translateY(-2px);background:linear-gradient(135deg,rgba(24,144,255,0.16),rgba(10,30,60,0.50));}');
|
||||
d=d.replace('.stat-card__num{font-size:24px;font-weight:700;color:#fff;line-height:1;text-shadow:0 0 8px rgba(255,255,255,0.2);}',
|
||||
'.stat-card__num{font-size:20px;font-weight:700;color:#fff;line-height:1;\r\n text-shadow:0 0 10px rgba(24,144,255,0.35);font-variant-numeric:tabular-nums;letter-spacing:0.5px;}');
|
||||
d=d.replace('.stat-card__label{font-size:11px;color:var(--text-sub);margin-top:6px;}',
|
||||
'.stat-card__label{font-size:10px;color:var(--text-sub);white-space:nowrap;letter-spacing:0.3px;}');
|
||||
for(const[old,nw] of[
|
||||
['.stat-card--danger .stat-card__num{color:var(--danger);text-shadow:0 0 8px rgba(255,77,79,0.3);}',
|
||||
'.stat-card--danger::before{background:var(--danger);box-shadow:0 0 8px rgba(255,77,79,0.55);}\r\n .stat-card--danger .stat-card__num{color:var(--danger);text-shadow:0 0 10px rgba(255,77,79,0.4);}\r\n .stat-card--danger::after{background:radial-gradient(ellipse at 100% 0%,rgba(255,77,79,0.06),transparent 55%);}\r\n .stat-card--danger:hover{border-color:rgba(255,77,79,0.3);box-shadow:0 0 16px rgba(255,77,79,0.15);}'],
|
||||
['.stat-card--warning .stat-card__num{color:var(--warning);text-shadow:0 0 8px rgba(250,173,20,0.3);}',
|
||||
'.stat-card--warning::before{background:var(--warning);box-shadow:0 0 8px rgba(250,173,20,0.55);}\r\n .stat-card--warning .stat-card__num{color:var(--warning);text-shadow:0 0 10px rgba(250,173,20,0.4);}\r\n .stat-card--warning::after{background:radial-gradient(ellipse at 100% 0%,rgba(250,173,20,0.06),transparent 55%);}\r\n .stat-card--warning:hover{border-color:rgba(250,173,20,0.3);box-shadow:0 0 16px rgba(250,173,20,0.15);}'],
|
||||
['.stat-card--success .stat-card__num{color:var(--success);text-shadow:0 0 8px rgba(82,196,26,0.3);}',
|
||||
'.stat-card--success::before{background:var(--success);box-shadow:0 0 8px rgba(82,196,26,0.55);}\r\n .stat-card--success .stat-card__num{color:var(--success);text-shadow:0 0 10px rgba(82,196,26,0.4);}\r\n .stat-card--success::after{background:radial-gradient(ellipse at 100% 0%,rgba(82,196,26,0.06),transparent 55%);}\r\n .stat-card--success:hover{border-color:rgba(82,196,26,0.3);box-shadow:0 0 16px rgba(82,196,26,0.15);}']
|
||||
]) d=d.replace(old,nw);
|
||||
d=d.replace('/* ========== 左侧:服务详情 ========== */','/* ========== 左侧:应急事件统计卡片 ========== */');
|
||||
|
||||
// CSS: alarm-bars + radar
|
||||
d=d.replace(' /* ========== 左侧:体检数据排行 ========== */',
|
||||
` /* ========== 左侧:穿戴告警统计柱状图 ========== */
|
||||
.panel--alarm-bars .panel__body{padding:8px 10px 10px;overflow:hidden;}
|
||||
.alarm-bars{display:flex;flex-direction:column;gap:7px;}
|
||||
.alarm-bars__row{display:flex;align-items:center;gap:8px;min-height:22px;}
|
||||
.alarm-bars__label{width:54px;font-size:10px;color:var(--text-sub);text-align:right;flex-shrink:0;white-space:nowrap;line-height:1.2;}
|
||||
.alarm-bars__track{flex:1;height:12px;background:rgba(24,144,255,0.06);border-radius:6px;overflow:hidden;position:relative;}
|
||||
.alarm-bars__bar{height:100%;border-radius:6px;transition:width .6s ease;position:relative;min-width:4px;}
|
||||
.alarm-bars__bar::after{content:"";position:absolute;right:0;top:0;bottom:0;width:2px;background:rgba(255,255,255,0.25);border-radius:0 6px 6px 0;}
|
||||
.alarm-bars__count{width:32px;font-size:11px;font-weight:700;color:#fff;text-align:right;flex-shrink:0;font-variant-numeric:tabular-nums;}
|
||||
|
||||
/* ========== 右侧:体检数据雷达图 ========== */
|
||||
.panel--checkup-radar .panel__body{padding:6px 10px 8px;overflow:hidden;}
|
||||
.checkup-radar{display:flex;align-items:center;justify-content:center;}
|
||||
.checkup-radar svg{width:100%;max-width:280px;height:auto;display:block;}
|
||||
.radar-dot{animation:radarPulse 2s ease-in-out infinite;filter:drop-shadow(0 0 4px rgba(24,144,255,0.6));}
|
||||
@keyframes radarPulse{0%,100%{opacity:0.6;r:2.5;}50%{opacity:1;r:3.5;}}
|
||||
|
||||
/* ========== 左侧:体检数据排行 ========== */`);
|
||||
|
||||
// CSS: AI risk tooltip
|
||||
d=d.replace('.ai-risk-col{min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px;}',
|
||||
'.ai-risk-col{min-width:0;display:flex;flex-direction:column;align-items:center;gap:4px;position:relative;}');
|
||||
d=d.replace('.ai-risk-stack{height:72px;width:32px;display:flex;flex-direction:column;justify-content:flex-end;\r\n border-radius:5px 5px 3px 3px;overflow:hidden;background:rgba(24,144,255,0.06);\r\n box-shadow:inset 0 0 0 1px rgba(24,144,255,0.12);}',
|
||||
'.ai-risk-stack{height:72px;width:32px;display:flex;flex-direction:column;justify-content:flex-end;\r\n border-radius:5px 5px 3px 3px;overflow:hidden;background:rgba(24,144,255,0.06);\r\n box-shadow:inset 0 0 0 1px rgba(24,144,255,0.12);cursor:pointer;}\r\n .ai-risk-stack:hover{border-color:rgba(24,144,255,0.4);}\r\n .ai-risk-tip{position:absolute;bottom:80px;left:50%;transform:translateX(-50%);z-index:30;\r\n background:rgba(10,22,48,0.96);border:1px solid rgba(24,144,255,0.35);border-radius:8px;\r\n padding:8px 10px;white-space:nowrap;pointer-events:none;\r\n opacity:0;transition:opacity .2s,bottom .2s;\r\n box-shadow:0 4px 18px rgba(0,0,0,0.5),0 0 12px rgba(24,144,255,0.15);\r\n font-size:11px;color:var(--text-sub);line-height:1.7;text-align:left;}\r\n .ai-risk-tip::after{content:\"\";position:absolute;top:100%;left:50%;transform:translateX(-50%);\r\n width:0;height:0;border-left:5px solid transparent;border-right:5px solid transparent;\r\n border-top:5px solid rgba(10,22,48,0.96);}\r\n .ai-risk-tip b{font-weight:600;}\r\n .ai-risk-col:hover .ai-risk-tip{opacity:1;bottom:84px;}');
|
||||
console.log('CSS all done');
|
||||
|
||||
// ═══ HTML: Read 4th stat-card directly from file ═══
|
||||
const ljsl=d.indexOf('累计受理次数');
|
||||
const cardBeg=d.lastIndexOf('<div class="stat-card',ljsl);
|
||||
const gridEnd=d.indexOf('</div>\r\n </div>',ljsl);
|
||||
const card4=d.substring(cardBeg,gridEnd);
|
||||
let card4n=card4.replace('累计受理次数','累计工单');
|
||||
card4n+='\r\n <div class="stat-card stat-card--warning" onclick="openWorkOrderStat(\'待处理\');event.stopPropagation();"><div class="stat-card__num">156</div><div class="stat-card__label">待处理工单</div></div>\r\n <div class="stat-card" onclick="openWorkOrderStat(\'已完成\');event.stopPropagation();"><div class="stat-card__num">3,232</div><div class="stat-card__label">已完成工单</div></div>';
|
||||
d=d.replace(card4,card4n);
|
||||
ok(d.includes('待处理工单'),'6 stat cards');
|
||||
|
||||
// ═══ HTML: Replace help events with alarm bars ═══
|
||||
const helpBeg=d.indexOf(' <!-- 应急求助事件(自动滚动列表) -->');
|
||||
const healthBeg=d.indexOf(' <!-- 人员现状监测(环形图) -->');
|
||||
const helpBlock=d.substring(helpBeg,healthBeg);
|
||||
const alarmBars=` <!-- 穿戴告警统计(柱状图) -->
|
||||
<div class="panel panel--alarm-bars" style="flex-shrink:0;">
|
||||
<div class="panel__header">
|
||||
<div class="panel__header-diamond"></div>
|
||||
<span class="panel__header-title">穿戴告警统计</span>
|
||||
<select class="panel__header-select" onchange="switchAlarmBarPeriod(this.value)">
|
||||
<option value="week" selected>近一周</option>
|
||||
<option value="month">近一月</option>
|
||||
<option value="year">近一年</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="panel__body">
|
||||
<div class="alarm-bars" id="alarmBarsChart">
|
||||
<div class="alarm-bars__row"><span class="alarm-bars__label">心率异常</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:100%;background:#FF4D4F;box-shadow:0 0 8px #FF4D4F;"></div></div><span class="alarm-bars__count">126</span></div>
|
||||
<div class="alarm-bars__row"><span class="alarm-bars__label">体温异常</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:42.9%;background:#FAAD14;box-shadow:0 0 8px #FAAD14;"></div></div><span class="alarm-bars__count">54</span></div>
|
||||
<div class="alarm-bars__row"><span class="alarm-bars__label">血氧异常</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:30.2%;background:#b37feb;box-shadow:0 0 8px #b37feb;"></div></div><span class="alarm-bars__count">38</span></div>
|
||||
<div class="alarm-bars__row"><span class="alarm-bars__label">压力异常</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:57.1%;background:#1890FF;box-shadow:0 0 8px #1890FF;"></div></div><span class="alarm-bars__count">72</span></div>
|
||||
<div class="alarm-bars__row"><span class="alarm-bars__label">一键告警</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:14.3%;background:#ff7875;box-shadow:0 0 8px #ff7875;"></div></div><span class="alarm-bars__count">18</span></div>
|
||||
<div class="alarm-bars__row"><span class="alarm-bars__label">摔倒</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:7.1%;background:#f5222d;box-shadow:0 0 8px #f5222d;"></div></div><span class="alarm-bars__count">9</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
`;
|
||||
d=d.replace(helpBlock,alarmBars);
|
||||
ok(d.includes('alarmBarsChart')&&!d.includes('应急求助事件(自动滚动列表)'),'alarm bars + remove help');
|
||||
|
||||
// ═══ HTML: Move AI from right to left ═══
|
||||
const aiBeg=d.indexOf('a id="aiPanel"');
|
||||
const aiBlockStart=d.lastIndexOf(' <!-- AI智能预警分析 -->',aiBeg);
|
||||
const rAside=d.lastIndexOf(' </aside>');
|
||||
const aiBlock=d.substring(aiBlockStart,rAside);
|
||||
d=d.split(aiBlock).join('');// Remove from right
|
||||
// Insert before 人员现状监测 on left
|
||||
const healthPos=d.indexOf(' <!-- 人员现状监测(环形图) -->');
|
||||
d=d.substring(0,healthPos)+aiBlock+'\r\n'+d.substring(healthPos);
|
||||
ok(d.includes('AI智能预警分析'),'AI moved to left');
|
||||
|
||||
// ═══ HTML: AI rename + dropdown + tooltips ═══
|
||||
d=d.replace('AI智能预警分析</span>','心脑血管预警统计<span class="panel__header-link" style="margin-left:4px;" onclick="openCvRecordModal();event.stopPropagation();">(历史记录)</span></span>');
|
||||
d=d.replace(' <!-- AI智能预警分析 -->',' <!-- 心脑血管预警统计 -->');
|
||||
// Remove old history link, add dropdown
|
||||
const histBeg=d.indexOf('pan>历史记录</span>');
|
||||
const linkLineStart=d.lastIndexOf('<!-- [交互] 点击查看',histBeg);
|
||||
const linkLineEnd=d.indexOf('\r\n',histBeg);
|
||||
d=d.substring(0,linkLineStart)+'<select class="panel__header-select" onchange="switchCvPeriod(this.value)"><option value="week" selected>近一周</option><option value="month">近一月</option><option value="year">近一年</option></select>'+d.substring(linkLineEnd);
|
||||
// Remove title attrs
|
||||
['心梗:高危1、中危2、低危3','脑梗:高危1、中危1、低危4','脑出血:高危1、中危1、低危2','猝死:高危0、中危1、低危3'].forEach(t=>{
|
||||
const p=d.indexOf('title="'+t+'"');if(p>0)d=d.substring(0,p)+d.substring(p+t.length+8);
|
||||
});
|
||||
// Add tooltips + update legend
|
||||
[{n:'心梗',t:'<div class="ai-risk-tip"><b style="color:#ff7875;">高危</b> 1 <b style="color:#ffc53d;">中危</b> 2 <b style="color:#40a9ff;">低危</b> 3</div>'},
|
||||
{n:'脑梗',t:'<div class="ai-risk-tip"><b style="color:#ff7875;">高危</b> 1 <b style="color:#ffc53d;">中危</b> 1 <b style="color:#40a9ff;">低危</b> 4</div>'},
|
||||
{n:'脑出血',t:'<div class="ai-risk-tip"><b style="color:#ff7875;">高危</b> 1 <b style="color:#ffc53d;">中危</b> 1 <b style="color:#40a9ff;">低危</b> 2</div>'},
|
||||
{n:'猝死',t:'<div class="ai-risk-tip"><b style="color:#ffc53d;">中危</b> 1 <b style="color:#40a9ff;">低危</b> 3</div>'}].forEach(x=>{
|
||||
d=d.replace('<div class="ai-risk-col__name">'+x.n+'</div>',x.t+'\r\n <div class="ai-risk-col__name">'+x.n+'</div>');
|
||||
});
|
||||
d=d.replace('</i>高危</span>','</i>高危 3</span>');
|
||||
d=d.replace('</i>中危</span>','</i>中危 5</span>');
|
||||
d=d.replace('</i>低危</span>','</i>低危 12</span>');
|
||||
ok(d.includes('心脑血管预警统计'),'AI panel updated');
|
||||
|
||||
// ═══ HTML: Right panel → 体检数据 + 咨询数据 ═══
|
||||
const rpBeg=d.indexOf(' <!-- 右侧面板 -->');
|
||||
const rpEnd=d.indexOf(' </aside>',rpBeg);
|
||||
const nrp=` <!-- 右侧面板 -->
|
||||
<aside class="side">
|
||||
<!-- 体检数据(雷达图) -->
|
||||
<div class="panel panel--checkup-radar" style="flex-shrink:0;">
|
||||
<div class="panel__header">
|
||||
<div class="panel__header-diamond"></div>
|
||||
<span class="panel__header-title">体检数据</span>
|
||||
<select class="panel__header-select" onchange="switchCheckupPeriod(this.value)">
|
||||
<option value="week" selected>近一周</option>
|
||||
<option value="month">近一月</option>
|
||||
<option value="year">近一年</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="panel__body">
|
||||
<div class="checkup-radar" id="checkupRadar">
|
||||
<svg viewBox="0 0 240 240" aria-hidden="true">
|
||||
<polygon points="120,30 198,75 198,165 120,210 42,165 42,75" fill="none" stroke="rgba(24,144,255,0.10)" stroke-width="0.8"/>
|
||||
<polygon points="120,60 172,90 172,150 120,180 68,150 68,90" fill="none" stroke="rgba(24,144,255,0.14)" stroke-width="0.8"/>
|
||||
<polygon points="120,90 146,105 146,135 120,150 94,135 94,105" fill="none" stroke="rgba(24,144,255,0.18)" stroke-width="0.8"/>
|
||||
<line x1="120" y1="120" x2="120" y2="30" stroke="rgba(24,144,255,0.10)" stroke-width="0.6"/>
|
||||
<line x1="120" y1="120" x2="198" y2="75" stroke="rgba(24,144,255,0.10)" stroke-width="0.6"/>
|
||||
<line x1="120" y1="120" x2="198" y2="165" stroke="rgba(24,144,255,0.10)" stroke-width="0.6"/>
|
||||
<line x1="120" y1="120" x2="120" y2="210" stroke="rgba(24,144,255,0.10)" stroke-width="0.6"/>
|
||||
<line x1="120" y1="120" x2="42" y2="165" stroke="rgba(24,144,255,0.10)" stroke-width="0.6"/>
|
||||
<line x1="120" y1="120" x2="42" y2="75" stroke="rgba(24,144,255,0.10)" stroke-width="0.6"/>
|
||||
<polygon id="checkupRadarPoly" points="120,44 180,85 165,146 120,164 65,152 72,92" fill="rgba(24,144,255,0.18)" stroke="var(--primary)" stroke-width="1.8" stroke-linejoin="round" style="filter:drop-shadow(0 0 4px rgba(24,144,255,0.4));"/>
|
||||
<circle cx="120" cy="44" r="2.5" fill="var(--primary)" class="radar-dot"/><circle cx="180" cy="85" r="2.5" fill="var(--primary)" class="radar-dot"/>
|
||||
<circle cx="165" cy="146" r="2.5" fill="var(--primary)" class="radar-dot"/><circle cx="120" cy="164" r="2.5" fill="var(--primary)" class="radar-dot"/>
|
||||
<circle cx="65" cy="152" r="2.5" fill="var(--primary)" class="radar-dot"/><circle cx="72" cy="92" r="2.5" fill="var(--primary)" class="radar-dot"/>
|
||||
<text x="120" y="38" fill="#fff" font-size="9" text-anchor="middle" font-weight="700">420</text>
|
||||
<text x="190" y="82" fill="#fff" font-size="9" text-anchor="start" font-weight="700">385</text>
|
||||
<text x="172" y="152" fill="#fff" font-size="9" text-anchor="start" font-weight="700">290</text>
|
||||
<text x="120" y="178" fill="#fff" font-size="9" text-anchor="middle" font-weight="700">245</text>
|
||||
<text x="50" y="152" fill="#fff" font-size="9" text-anchor="end" font-weight="700">350</text>
|
||||
<text x="58" y="88" fill="#fff" font-size="9" text-anchor="end" font-weight="700">310</text>
|
||||
<text x="120" y="18" fill="var(--text-sub)" font-size="10" text-anchor="middle">兴隆医院</text>
|
||||
<text x="208" y="73" fill="var(--text-sub)" font-size="10" text-anchor="start">宝石花医院</text>
|
||||
<text x="208" y="170" fill="var(--text-sub)" font-size="10" text-anchor="start">庆阳医院</text>
|
||||
<text x="120" y="226" fill="var(--text-sub)" font-size="10" text-anchor="middle">高陵医院</text>
|
||||
<text x="32" y="170" fill="var(--text-sub)" font-size="10" text-anchor="end">采油一厂</text>
|
||||
<text x="32" y="73" fill="var(--text-sub)" font-size="10" text-anchor="end">采油二厂</text>
|
||||
<circle cx="120" cy="120" r="2" fill="rgba(24,144,255,0.5)"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 咨询数据 -->
|
||||
<div class="panel" style="flex-shrink:0;">
|
||||
<div class="panel__header"><div class="panel__header-diamond"></div><span class="panel__header-title">咨询数据</span></div>
|
||||
<div class="panel__body">
|
||||
<div class="stat-grid">
|
||||
<div class="stat-card"><div class="stat-card__num">48</div><div class="stat-card__label">入驻专家</div></div>
|
||||
<div class="stat-card stat-card--success"><div class="stat-card__num">12,580</div><div class="stat-card__label">累计咨询次数</div></div>
|
||||
<div class="stat-card stat-card--warning"><div class="stat-card__num">6,342</div><div class="stat-card__label">累计咨询人数</div></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>`;
|
||||
d=d.replace(d.substring(rpBeg,rpEnd),nrp);
|
||||
ok(d.includes('checkupRadar')&&d.includes('咨询数据'),'Right panel');
|
||||
|
||||
// ═══ JS: openWorkOrderStat ═══
|
||||
d=d.replace('function closeHelpRecordModal(){',
|
||||
'function openWorkOrderStat(status){var range=getHelpRecordDateRangeByPeriod(currentEmergencyStatPeriod);document.getElementById("helpRecordOverlay").style.display="flex";document.getElementById("filterHelpType").value="";document.getElementById("filterHelpStatus").value=status||"";document.getElementById("filterHelpDateFrom").value=range.from;document.getElementById("filterHelpDateTo").value=range.to;document.getElementById("filterHelpName").value="";document.getElementById("filterHelpEmpId").value="";helpRecordPageSizeVal=parseInt(document.getElementById("helpRecordPageSize").value)||10;applyHelpRecordFilter();}\r\nfunction closeHelpRecordModal(){');
|
||||
|
||||
// ═══ JS: All modules + init ═══
|
||||
const jsModules=`/* ========== 穿戴告警统计 ========== */
|
||||
var currentAlarmBarPeriod="week";var ALARM_BAR_BASE=[{label:"心率异常",value:126,color:"#FF4D4F"},{label:"体温异常",value:54,color:"#FAAD14"},{label:"血氧异常",value:38,color:"#b37feb"},{label:"压力异常",value:72,color:"#1890FF"},{label:"一键告警",value:18,color:"#ff7875"},{label:"摔倒",value:9,color:"#f5222d"}];var ALARM_BAR_PERIOD_FACTOR={week:1,month:4.2,year:12.5};function switchAlarmBarPeriod(p){currentAlarmBarPeriod=p||"week";renderAlarmBars();}
|
||||
function renderAlarmBars(){var f=ALARM_BAR_PERIOD_FACTOR[currentAlarmBarPeriod]||1;var d=ALARM_BAR_BASE.map(function(d){return{label:d.label,value:Math.round(d.value*f),color:d.color};});var m=Math.max.apply(null,d.map(function(d){return d.value;}));var c=document.getElementById("alarmBarsChart");if(!c)return;var h="";d.forEach(function(d){var p=m>0?(d.value/m*100):0;h+='<div class="alarm-bars__row"><span class="alarm-bars__label">'+d.label+'</span><div class="alarm-bars__track"><div class="alarm-bars__bar" style="width:'+p+'%;background:'+d.color+';box-shadow:0 0 8px '+d.color+';"></div></div><span class="alarm-bars__count">'+d.value+'</span></div>';});c.innerHTML=h;}
|
||||
|
||||
/* ========== 心脑血管预警统计 ========== */
|
||||
var currentCvPeriod="week";var CV_PERIOD_FACTOR={week:1,month:3.8,year:11.5};var CV_BASE_DATA={todayWarn:20,highRisk:3,yesterdayChange:"+12%",diseases:[{name:"心梗",high:1,mid:2,low:3},{name:"脑梗",high:1,mid:1,low:4},{name:"脑出血",high:1,mid:1,low:2},{name:"猝死",high:0,mid:1,low:3}],legend:{high:3,mid:5,low:12}};function switchCvPeriod(p){currentCvPeriod=p||"week";updateCvStats();}
|
||||
function cvPeriodLabel(){var m={week:"本周",month:"本月",year:"本年"};return m[currentCvPeriod]||"本周";}
|
||||
function updateCvStats(){var f=CV_PERIOD_FACTOR[currentCvPeriod]||1,p=document.getElementById("aiPanel");if(!p)return;var b=p.querySelector(".panel__body");if(!b)return;var w=Math.round(CV_BASE_DATA.todayWarn*f),hi=Math.round(CV_BASE_DATA.highRisk*f),ds=CV_BASE_DATA.diseases,l=CV_BASE_DATA.legend,lH=Math.round(l.high*f),lM=Math.round(l.mid*f),lL=Math.round(l.low*f),mx=Math.max.apply(null,ds.map(function(d){return(d.high+d.mid+d.low)*f;})),h=mx>0?function(v){return Math.max(4,Math.round(v*f/mx*72));}:function(){return 0;};var html='<div class="ai-analysis"><div class="ai-analysis__summary"><div class="ai-analysis__metric"><div class="ai-analysis__metric-num">'+w+'</div><div class="ai-analysis__metric-label">'+cvPeriodLabel()+'预警</div></div><div class="ai-analysis__metric ai-analysis__metric--danger"><div class="ai-analysis__metric-num">'+hi+'</div><div class="ai-analysis__metric-label">高危人数</div></div><div class="ai-analysis__metric ai-analysis__metric--warning"><div class="ai-analysis__metric-num">'+CV_BASE_DATA.yesterdayChange+'</div><div class="ai-analysis__metric-label">较昨日</div></div></div><div class="ai-analysis__section-head"><b>预警分布</b><span>按疾病类型/风险等级</span></div><div class="ai-risk-chart">';ds.forEach(function(d){var hh=h(d.high),hm=h(d.mid),hl=h(d.low),vh=Math.round(d.high*f),vm=Math.round(d.mid*f),vl=Math.round(d.low*f),c=vh+vm+vl,tp=[];if(d.high>0)tp.push('<b style="color:#ff7875;">高危</b> '+vh);if(d.mid>0)tp.push('<b style="color:#ffc53d;">中危</b> '+vm);if(d.low>0)tp.push('<b style="color:#40a9ff;">低危</b> '+vl);html+='<div class="ai-risk-col"><div class="ai-risk-stack">'+(d.high>0?'<span class="ai-risk-stack__seg ai-risk-stack__seg--high" style="height:'+hh+'px;"></span>':'')+(d.mid>0?'<span class="ai-risk-stack__seg ai-risk-stack__seg--mid" style="height:'+hm+'px;"></span>':'')+(d.low>0?'<span class="ai-risk-stack__seg ai-risk-stack__seg--low" style="height:'+hl+'px;"></span>':'')+'</div><div class="ai-risk-tip">'+tp.join(' ')+'</div><div class="ai-risk-col__name">'+d.name+'</div><div class="ai-risk-col__count">'+c+'</div></div>';});html+='</div><div class="ai-analysis__legend"><span><i style="background:var(--danger);color:var(--danger);"></i>高危 '+lH+'</span><span><i style="background:var(--warning);color:var(--warning);"></i>中危 '+lM+'</span><span><i style="background:var(--primary);color:var(--primary);"></i>低危 '+lL+'</span></div></div>';b.innerHTML=html;}
|
||||
|
||||
/* ========== 体检数据 ========== */
|
||||
var currentCheckupPeriod="week";var CHECKUP_BASE=[{name:"兴隆医院",value:420,angle:-90},{name:"宝石花医院",value:385,angle:-30},{name:"庆阳医院",value:290,angle:30},{name:"高陵医院",value:245,angle:90},{name:"采油一厂",value:350,angle:150},{name:"采油二厂",value:310,angle:210}];var CHECKUP_PERIOD_FACTOR={week:1,month:3.6,year:10.8};function switchCheckupPeriod(p){currentCheckupPeriod=p||"week";updateCheckupRadar();}
|
||||
function updateCheckupRadar(){var poly=document.getElementById("checkupRadarPoly");if(!poly)return;var f=CHECKUP_PERIOD_FACTOR[currentCheckupPeriod]||1,cx=120,cy=120,mR=90,mV=500*f;var pts=CHECKUP_BASE.map(function(d){var r=Math.min(mR,d.value*f/mV*mR);return(cx+r*Math.cos(d.angle*Math.PI/180)).toFixed(0)+","+(cy+r*Math.sin(d.angle*Math.PI/180)).toFixed(0);});poly.setAttribute("points",pts.join(" "));}
|
||||
|
||||
/* [初始化] */
|
||||
renderAlarmBars();`;
|
||||
d=d.replace('/* [初始化] 页面加载时默认渲染心率区间环形图 */\r\nupdateWearableDistribution();',jsModules);
|
||||
ok(d.includes('renderAlarmBars')&&d.includes('updateCvStats'),'JS modules');
|
||||
|
||||
// ═══ FINAL ═══
|
||||
const cnt=s=>(d.split(s).length-1);
|
||||
console.log('\n=== FINAL ===');
|
||||
console.log('aside:',cnt('</aside>'),'right:',cnt('<!-- 右侧面板 -->'),'left:',cnt('<!-- 左侧面板 -->'));
|
||||
console.log('6cards:',cnt('待处理工单'),'alarm:',cnt('alarmBarsChart'),'help:',cnt('应急求助事件(自动滚动列表)'));
|
||||
console.log('CV:',cnt('心脑血管预警统计'),'radar:',cnt('checkupRadar'),'consult:',cnt('咨询数据'));
|
||||
console.log('health:',cnt('人员现状监测(环形图)'),'renderAlarmBars:',cnt('renderAlarmBars'),'updateCvStats:',cnt('updateCvStats'));
|
||||
fs.writeFileSync(f,d,'utf8');
|
||||
console.log('DONE. Size:',d.length);
|
||||
@@ -112,7 +112,7 @@
|
||||
<a class="tab-item" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item active" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -42,6 +42,35 @@
|
||||
content: ''; width: 120px; height: 5px; background: #1a1a1a;
|
||||
border-radius: 3px; opacity: 0.2;
|
||||
}
|
||||
/* 订单类型 Tab */
|
||||
.type-tabs { display: flex; background: #fff; border-bottom: 0.5px solid #f0f0f0; padding: 0 16px; flex-shrink: 0; }
|
||||
.type-tab {
|
||||
flex: 1; text-align: center; padding: 12px 0; font-size: 14px; color: #666;
|
||||
position: relative; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 4px;
|
||||
}
|
||||
.type-tab.active { color: #1677ff; font-weight: 600; }
|
||||
.type-tab.active::after {
|
||||
content: ''; position: absolute; bottom: 0; left: 30%; right: 30%; height: 2px;
|
||||
background: #1677ff; border-radius: 1px;
|
||||
}
|
||||
.type-tab .tab-count {
|
||||
font-size: 11px; min-width: 18px; height: 18px; line-height: 18px; padding: 0 5px;
|
||||
background: #f0f0f0; color: #666; border-radius: 9px; font-weight: 600;
|
||||
}
|
||||
.type-tab.active .tab-count { background: #e6f4ff; color: #1677ff; }
|
||||
.type-tab .presale-tag {
|
||||
font-size: 10px; padding: 0 4px; background: #fff7e6; color: #fa8c16;
|
||||
border-radius: 3px; font-weight: 600;
|
||||
}
|
||||
.cart-panel.hidden { display: none; }
|
||||
/* 净菜包预售提示 */
|
||||
.presale-hint {
|
||||
display: flex; align-items: flex-start; gap: 8px;
|
||||
margin: 8px 12px; padding: 10px 12px;
|
||||
background: #fff7e6; border-radius: 8px; font-size: 12px; color: #fa8c16; line-height: 1.5;
|
||||
}
|
||||
.presale-hint .hint-icon { font-size: 14px; flex-shrink: 0; }
|
||||
.presale-hint b { font-weight: 600; }
|
||||
/* 购物车商品列表 */
|
||||
.cart-section { background: #fff; margin-bottom: 8px; }
|
||||
.cart-section .sec-title {
|
||||
@@ -116,7 +145,14 @@
|
||||
<span class="title">购物车</span>
|
||||
<button class="clear-btn">清空</button>
|
||||
</div>
|
||||
<!-- 订单类型 Tab -->
|
||||
<div class="type-tabs">
|
||||
<div class="type-tab active" data-type="meal">🍽️ 餐品 <span class="tab-count" id="count-meal">3</span></div>
|
||||
<div class="type-tab" data-type="clean">🥬 餐品净菜包 <span class="presale-tag">预售</span> <span class="tab-count" id="count-clean">2</span></div>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<!-- 餐品组(即时点餐) -->
|
||||
<div class="cart-panel" id="panel-meal">
|
||||
<!-- 已选菜品 -->
|
||||
<div class="cart-section">
|
||||
<div class="sec-title">已选菜品(3)</div>
|
||||
@@ -183,17 +219,110 @@
|
||||
<div class="sec-title">备注</div>
|
||||
<input class="remark-input" placeholder="如:少辣、不要香菜..." readonly>
|
||||
</div>
|
||||
</div><!-- /panel-meal -->
|
||||
|
||||
<!-- 餐品净菜包组(预售) -->
|
||||
<div class="cart-panel hidden" id="panel-clean">
|
||||
<div class="presale-hint">
|
||||
<span class="hint-icon">⚠️</span>
|
||||
<span>净菜包为<b>预售商品</b>,请在结算时选择<b>取货方式</b>(配送到家 / 食堂自提)和<b>期望配送时间</b>;当日 15:00 前订单次日配送。</span>
|
||||
</div>
|
||||
<div class="cart-section">
|
||||
<div class="sec-title">已选净菜包(2)</div>
|
||||
<div class="cart-item">
|
||||
<div class="food-icon">🍗</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">宫保鸡丁净菜包</div>
|
||||
<div class="food-meta">约300g · 285kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥22</span>
|
||||
<div class="qty-ctrl">
|
||||
<button class="qty-btn">−</button>
|
||||
<span class="qty-num">2</span>
|
||||
<button class="qty-btn">+</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cart-item">
|
||||
<div class="food-icon">🥗</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">低脂控糖套餐净菜包</div>
|
||||
<div class="food-meta">约400g · 320kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥35</span>
|
||||
<div class="qty-ctrl">
|
||||
<button class="qty-btn">−</button>
|
||||
<span class="qty-num">1</span>
|
||||
<button class="qty-btn">+</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="remark-section">
|
||||
<div class="sec-title">备注</div>
|
||||
<input class="remark-input" placeholder="如:多放调料、不要香菜..." readonly>
|
||||
</div>
|
||||
</div><!-- /panel-clean -->
|
||||
</div>
|
||||
|
||||
<!-- 底部结算栏 -->
|
||||
<div class="settle-bar">
|
||||
<div class="settle-info">
|
||||
<div class="settle-total">合计 <span class="amount">¥38.00</span></div>
|
||||
<div class="settle-desc">已享员工餐补优惠</div>
|
||||
<div class="settle-total">合计 <span class="amount" id="settleAmount">¥38.00</span></div>
|
||||
<div class="settle-desc" id="settleDesc">已享员工餐补优惠</div>
|
||||
</div>
|
||||
<a class="settle-btn" href="eat-order-confirm.html">提交订单</a>
|
||||
<a class="settle-btn" id="settleBtn" href="eat-order-confirm.html?type=meal">提交订单</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
<script>
|
||||
/* 解析 URL 参数,决定初始展示哪个组 */
|
||||
function getQuery(name) {
|
||||
var m = new RegExp('[?&]' + name + '=([^&]*)').exec(location.search);
|
||||
return m ? decodeURIComponent(m[1]) : '';
|
||||
}
|
||||
|
||||
var currentType = getQuery('type') === 'clean' ? 'clean' : 'meal';
|
||||
var settleAmount = document.getElementById('settleAmount');
|
||||
var settleDesc = document.getElementById('settleDesc');
|
||||
var settleBtn = document.getElementById('settleBtn');
|
||||
var countMeal = document.getElementById('count-meal');
|
||||
var countClean = document.getElementById('count-clean');
|
||||
|
||||
/* 各组小计数据(原型演示) */
|
||||
var panelData = {
|
||||
meal: { total: 38.00, desc: '已享员工餐补优惠', count: 3 },
|
||||
clean: { total: 79.00, desc: '预售 · 次日配送', count: 2 }
|
||||
};
|
||||
|
||||
/* 切换订单类型组:联动列表、底部合计、结算链接 */
|
||||
function switchType(type) {
|
||||
currentType = type;
|
||||
document.querySelectorAll('.type-tab').forEach(function(tab) {
|
||||
tab.classList.toggle('active', tab.dataset.type === type);
|
||||
});
|
||||
document.getElementById('panel-meal').classList.toggle('hidden', type !== 'meal');
|
||||
document.getElementById('panel-clean').classList.toggle('hidden', type !== 'clean');
|
||||
var d = panelData[type];
|
||||
settleAmount.textContent = '¥' + d.total.toFixed(2);
|
||||
settleDesc.textContent = d.desc;
|
||||
settleBtn.href = 'eat-order-confirm.html?type=' + type;
|
||||
}
|
||||
|
||||
document.querySelectorAll('.type-tab').forEach(function(tab) {
|
||||
tab.addEventListener('click', function() {
|
||||
switchType(tab.dataset.type);
|
||||
});
|
||||
});
|
||||
|
||||
/* 同步 Tab 数量徽标 */
|
||||
countMeal.textContent = panelData.meal.count;
|
||||
countClean.textContent = panelData.clean.count;
|
||||
|
||||
/* 初始化 */
|
||||
switchType(currentType);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -165,7 +165,7 @@
|
||||
<a class="tab-item active" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<!-- Home Indicator -->
|
||||
<div class="home-indicator"></div>
|
||||
|
||||
@@ -327,7 +327,7 @@
|
||||
<a class="tab-item active" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -51,6 +51,146 @@
|
||||
.order-total { display: flex; justify-content: space-between; padding-top: 12px; border-top: 1px solid #f0f0f0; margin-top: 8px; }
|
||||
.order-total .label { font-size: 14px; font-weight: 600; }
|
||||
.order-total .amount { font-size: 18px; font-weight: 800; color: #f5222d; }
|
||||
/* 净菜包履约信息卡 */
|
||||
.fulfill-card {
|
||||
margin: 0 16px 12px; background: #fff; border-radius: 12px; padding: 16px;
|
||||
}
|
||||
.fulfill-title {
|
||||
font-size: 14px; font-weight: 600; margin-bottom: 12px;
|
||||
display: flex; align-items: center; gap: 6px;
|
||||
}
|
||||
.fulfill-row {
|
||||
display: flex; padding: 8px 0; border-bottom: 0.5px solid #f5f5f5;
|
||||
font-size: 13px;
|
||||
}
|
||||
.fulfill-row:last-of-type { border-bottom: none; }
|
||||
.fr-label { width: 80px; color: #999; flex-shrink: 0; }
|
||||
.fr-value { flex: 1; color: #333; line-height: 1.5; }
|
||||
.fr-value.highlight { color: #fa8c16; font-weight: 600; }
|
||||
.fulfill-tip {
|
||||
margin-top: 10px; padding: 8px 10px; background: #fff7e6; border-radius: 6px;
|
||||
font-size: 11px; color: #fa8c16; line-height: 1.5;
|
||||
}
|
||||
.presale-tip {
|
||||
padding: 8px 10px; background: #fff7e6; border-radius: 6px;
|
||||
font-size: 11px; color: #fa8c16; line-height: 1.5; margin-bottom: 12px;
|
||||
}
|
||||
.presale-tip b { font-weight: 600; }
|
||||
/* 表单组 */
|
||||
.form-group { padding: 10px 0; border-bottom: 0.5px solid #f5f5f5; }
|
||||
.form-group:last-child { border-bottom: none; }
|
||||
.fg-label { font-size: 13px; font-weight: 600; color: #333; margin-bottom: 8px; }
|
||||
.fg-label .required { color: #f5222d; margin-left: 2px; }
|
||||
/* 取货方式 */
|
||||
.pickup-methods { display: flex; gap: 8px; }
|
||||
.pickup-method {
|
||||
flex: 1; padding: 10px 6px; border-radius: 10px; border: 1.5px solid #e8e8e8;
|
||||
text-align: center; cursor: pointer; background: #fff;
|
||||
}
|
||||
.pickup-method.active { border-color: #1677ff; background: #e6f4ff; }
|
||||
.pickup-method .pm-icon { font-size: 20px; }
|
||||
.pickup-method .pm-name { font-size: 13px; font-weight: 600; margin-top: 4px; color: #333; }
|
||||
.pickup-method .pm-desc { font-size: 10px; color: #999; margin-top: 2px; }
|
||||
.pickup-method.active .pm-name { color: #1677ff; }
|
||||
/* 日期/时段 chip */
|
||||
.chip-label { font-size: 11px; color: #999; margin: 8px 0 6px; }
|
||||
.date-chips, .time-chips { display: flex; gap: 6px; flex-wrap: wrap; }
|
||||
.date-chip, .time-chip {
|
||||
padding: 6px 10px; border-radius: 14px; background: #f5f5f5;
|
||||
font-size: 11px; color: #666; cursor: pointer; line-height: 1.4;
|
||||
}
|
||||
.date-chip.active, .time-chip.active {
|
||||
background: #1677ff; color: #fff; font-weight: 600;
|
||||
}
|
||||
/* 地址卡片 */
|
||||
.address-card, .pickup-card {
|
||||
padding: 12px; border-radius: 8px; border: 1px solid #e8e8e8; background: #fafafa;
|
||||
position: relative;
|
||||
}
|
||||
.addr-top { display: flex; align-items: center; gap: 8px; margin-bottom: 4px; flex-wrap: wrap; }
|
||||
.addr-name { font-size: 14px; font-weight: 600; color: #333; }
|
||||
.addr-phone { font-size: 12px; color: #666; }
|
||||
.addr-default { font-size: 10px; padding: 1px 6px; border-radius: 8px; background: #fff7e6; color: #fa8c16; font-weight: 600; }
|
||||
.addr-detail { font-size: 13px; color: #444; line-height: 1.5; padding-right: 56px; }
|
||||
.addr-edit { display: inline-block; font-size: 12px; color: #1677ff; margin-top: 6px; text-decoration: none; }
|
||||
.addr-switch {
|
||||
position: absolute; right: 10px; bottom: 10px; font-size: 12px; color: #1677ff;
|
||||
background: none; border: none; cursor: pointer; padding: 4px 6px;
|
||||
}
|
||||
/* 地址选择列表 */
|
||||
.addr-list { margin-top: 10px; display: none; }
|
||||
.addr-list.show { display: block; }
|
||||
.addr-option {
|
||||
padding: 10px 12px; border: 1px solid #e8e8e8; border-radius: 8px; background: #fff;
|
||||
margin-bottom: 8px; cursor: pointer; position: relative;
|
||||
}
|
||||
.addr-option.active { border-color: #1677ff; background: #f0f7ff; }
|
||||
.addr-option .opt-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
|
||||
.addr-option .opt-name { font-size: 14px; font-weight: 600; color: #333; }
|
||||
.addr-option .opt-phone { font-size: 12px; color: #666; }
|
||||
.addr-option .opt-default { font-size: 10px; padding: 1px 6px; border-radius: 8px; background: #fff7e6; color: #fa8c16; font-weight: 600; }
|
||||
.addr-option .opt-detail { font-size: 12px; color: #555; line-height: 1.5; padding-right: 28px; }
|
||||
.addr-option .opt-check {
|
||||
position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
|
||||
width: 18px; height: 18px; border-radius: 50%; border: 1.5px solid #d9d9d9;
|
||||
display: flex; align-items: center; justify-content: center; font-size: 12px; color: #fff;
|
||||
background: #fff;
|
||||
}
|
||||
.addr-option.active .opt-check { background: #1677ff; border-color: #1677ff; }
|
||||
.addr-option .opt-edit {
|
||||
position: absolute; right: 36px; top: 50%; transform: translateY(-50%);
|
||||
font-size: 11px; color: #1677ff; background: none; border: none; cursor: pointer;
|
||||
}
|
||||
.addr-add-btn {
|
||||
width: 100%; padding: 10px 0; border-radius: 8px; border: 1px dashed #1677ff;
|
||||
background: #fff; color: #1677ff; font-size: 13px; font-weight: 600; cursor: pointer;
|
||||
display: flex; align-items: center; justify-content: center; gap: 4px;
|
||||
}
|
||||
/* 新增地址表单 */
|
||||
.addr-form { margin-top: 10px; padding: 12px; border-radius: 8px; background: #fff; border: 1px solid #e8e8e8; display: none; }
|
||||
.addr-form.show { display: block; }
|
||||
.addr-form .form-row { padding: 8px 0; border-bottom: 0.5px solid #f5f5f5; }
|
||||
.addr-form .form-row:last-of-type { border-bottom: none; }
|
||||
.addr-form .form-label { font-size: 12px; color: #666; margin-bottom: 6px; }
|
||||
.addr-form .form-label .required { color: #f5222d; }
|
||||
.addr-form .form-input {
|
||||
width: 100%; height: 34px; border-radius: 6px; border: 1px solid #e8e8e8;
|
||||
padding: 0 10px; font-size: 13px; background: #f8f9fa; outline: none;
|
||||
}
|
||||
.addr-form .form-input:focus { border-color: #1677ff; background: #fff; }
|
||||
.addr-form .form-textarea {
|
||||
width: 100%; min-height: 60px; border-radius: 6px; border: 1px solid #e8e8e8;
|
||||
padding: 8px 10px; font-size: 13px; background: #f8f9fa; outline: none; resize: none; font-family: inherit;
|
||||
}
|
||||
.addr-form .form-textarea:focus { border-color: #1677ff; background: #fff; }
|
||||
.addr-form .form-switch {
|
||||
display: flex; align-items: center; justify-content: space-between; font-size: 13px; color: #333;
|
||||
}
|
||||
.switch-toggle {
|
||||
width: 36px; height: 20px; border-radius: 10px; background: #d9d9d9; position: relative;
|
||||
cursor: pointer; transition: background 0.2s; border: none;
|
||||
}
|
||||
.switch-toggle::after {
|
||||
content: ''; position: absolute; left: 2px; top: 2px; width: 16px; height: 16px;
|
||||
border-radius: 50%; background: #fff; transition: left 0.2s;
|
||||
}
|
||||
.switch-toggle.on { background: #1677ff; }
|
||||
.switch-toggle.on::after { left: 18px; }
|
||||
.addr-form-actions { display: flex; gap: 8px; margin-top: 12px; }
|
||||
.addr-form-actions .btn {
|
||||
flex: 1; height: 36px; border-radius: 18px; border: none; font-size: 13px;
|
||||
font-weight: 600; cursor: pointer;
|
||||
}
|
||||
.addr-form-actions .btn-cancel { background: #f5f5f5; color: #666; }
|
||||
.addr-form-actions .btn-save { background: #1677ff; color: #fff; }
|
||||
.pickup-name { font-size: 14px; font-weight: 600; color: #333; }
|
||||
.pickup-addr { font-size: 12px; color: #666; margin-top: 4px; }
|
||||
.pickup-time { font-size: 11px; color: #1677ff; margin-top: 4px; }
|
||||
.presale-status {
|
||||
font-size: 11px; padding: 2px 8px; border-radius: 8px;
|
||||
background: #fff7e6; color: #fa8c16; font-weight: 600;
|
||||
}
|
||||
.hidden { display: none !important; }
|
||||
.action-btns { padding: 16px; display: flex; gap: 12px; }
|
||||
.action-btns .btn {
|
||||
flex: 1; height: 44px; border-radius: 22px; border: none; font-size: 15px;
|
||||
@@ -73,28 +213,278 @@
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<div class="success-area">
|
||||
<div class="success-icon">✅</div>
|
||||
<div class="success-title">下单成功</div>
|
||||
<div class="success-desc">请凭取餐码到窗口取餐</div>
|
||||
<div class="success-icon" id="successIcon">✅</div>
|
||||
<div class="success-title" id="successTitle">下单成功</div>
|
||||
<div class="success-desc" id="successDesc">请凭取餐码到窗口取餐</div>
|
||||
</div>
|
||||
<div class="pickup-code">
|
||||
<!-- 餐品订单:取餐码(即时取餐) -->
|
||||
<div class="pickup-code" id="pickupBlock">
|
||||
<div class="label">取餐码</div>
|
||||
<div class="code">A086</div>
|
||||
<div class="hint">请在 30 分钟内取餐,超时将自动取消</div>
|
||||
</div>
|
||||
<!-- 净菜包订单:履约信息表单(预售,必填取货方式 + 期望时间) -->
|
||||
<div class="fulfill-card hidden" id="fulfillBlock">
|
||||
<div class="fulfill-title">📦 履约信息</div>
|
||||
<div class="presale-tip">⏰ 净菜包为<b>预售商品</b>,当日 <b>15:00 截单</b>,次日按所选时段配送/自提。</div>
|
||||
<!-- 取货方式 -->
|
||||
<div class="form-group">
|
||||
<div class="fg-label">取货方式 <span class="required">*</span></div>
|
||||
<div class="pickup-methods">
|
||||
<div class="pickup-method active" data-method="delivery">
|
||||
<div class="pm-icon">🚚</div>
|
||||
<div class="pm-name">配送到家</div>
|
||||
<div class="pm-desc">运费 ¥5(满79免)</div>
|
||||
</div>
|
||||
<div class="pickup-method" data-method="pickup">
|
||||
<div class="pm-icon">🏪</div>
|
||||
<div class="pm-name">食堂自提</div>
|
||||
<div class="pm-desc">免运费</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 期望配送时间 -->
|
||||
<div class="form-group">
|
||||
<div class="fg-label">期望配送时间 <span class="required">*</span></div>
|
||||
<div class="chip-label">选择日期</div>
|
||||
<div class="date-chips">
|
||||
<div class="date-chip">今日(4月28日)</div>
|
||||
<div class="date-chip active">明日(4月29日)</div>
|
||||
<div class="date-chip">4月30日</div>
|
||||
</div>
|
||||
<div class="chip-label">选择时段</div>
|
||||
<div class="time-chips">
|
||||
<div class="time-chip">早餐 07:00-08:00</div>
|
||||
<div class="time-chip active">午餐 11:00-12:00</div>
|
||||
<div class="time-chip">晚餐 17:00-18:00</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 配送地址(仅 delivery,支持选择/新增) -->
|
||||
<div class="form-group" id="addressGroup">
|
||||
<div class="fg-label">收货地址 <span class="required">*</span></div>
|
||||
<div class="address-card" id="addressCard">
|
||||
<div class="addr-top">
|
||||
<span class="addr-name" id="addrName">张三</span>
|
||||
<span class="addr-phone" id="addrPhone">138****6688</span>
|
||||
<span class="addr-default" id="addrDefaultTag">默认</span>
|
||||
</div>
|
||||
<div class="addr-detail" id="addrDetail">渝北区龙湖路123号4栋1单元1801</div>
|
||||
<button class="addr-switch" id="addrSwitchBtn">切换 ›</button>
|
||||
</div>
|
||||
<!-- 地址选择列表 -->
|
||||
<div class="addr-list" id="addrList">
|
||||
<div class="addr-option active" data-name="张三" data-phone="138****6688" data-detail="渝北区龙湖路123号4栋1单元1801" data-default="1">
|
||||
<div class="opt-top">
|
||||
<span class="opt-name">张三</span>
|
||||
<span class="opt-phone">138****6688</span>
|
||||
<span class="opt-default">默认</span>
|
||||
</div>
|
||||
<div class="opt-detail">渝北区龙湖路123号4栋1单元1801</div>
|
||||
<span class="opt-check">✓</span>
|
||||
</div>
|
||||
<div class="addr-option" data-name="张三" data-phone="138****6688" data-detail="南岸区江南大道28号写字楼12层" data-default="0">
|
||||
<div class="opt-top">
|
||||
<span class="opt-name">张三</span>
|
||||
<span class="opt-phone">138****6688</span>
|
||||
</div>
|
||||
<div class="opt-detail">南岸区江南大道28号写字楼12层</div>
|
||||
<span class="opt-check">✓</span>
|
||||
</div>
|
||||
<div class="addr-option" data-name="李四" data-phone="139****1234" data-detail="渝北区黄山大道中段55号2栋802" data-default="0">
|
||||
<div class="opt-top">
|
||||
<span class="opt-name">李四</span>
|
||||
<span class="opt-phone">139****1234</span>
|
||||
</div>
|
||||
<div class="opt-detail">渝北区黄山大道中段55号2栋802</div>
|
||||
<span class="opt-check">✓</span>
|
||||
</div>
|
||||
<button class="addr-add-btn" id="addrAddBtn">+ 新增收货地址</button>
|
||||
</div>
|
||||
<!-- 新增收货地址表单 -->
|
||||
<div class="addr-form" id="addrForm">
|
||||
<div class="form-row">
|
||||
<div class="form-label">收货人 <span class="required">*</span></div>
|
||||
<input class="form-input" placeholder="请输入收货人姓名">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-label">手机号 <span class="required">*</span></div>
|
||||
<input class="form-input" placeholder="请输入11位手机号">
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-label">所在地区 <span class="required">*</span></div>
|
||||
<input class="form-input" placeholder="省 / 市 / 区" readonly>
|
||||
</div>
|
||||
<div class="form-row">
|
||||
<div class="form-label">详细地址 <span class="required">*</span></div>
|
||||
<textarea class="form-textarea" placeholder="街道、楼牌号等"></textarea>
|
||||
</div>
|
||||
<div class="form-row form-switch">
|
||||
<span>设为默认收货地址</span>
|
||||
<button class="switch-toggle" id="addrDefaultToggle"></button>
|
||||
</div>
|
||||
<div class="addr-form-actions">
|
||||
<button class="btn btn-cancel" id="addrCancelBtn">取消</button>
|
||||
<button class="btn btn-save" id="addrSaveBtn">保存</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 自提点(仅 pickup) -->
|
||||
<div class="form-group hidden" id="pickupGroup">
|
||||
<div class="fg-label">自提点 <span class="required">*</span></div>
|
||||
<div class="pickup-card">
|
||||
<div class="pickup-name">CQ食堂A区 · 净菜自提柜</div>
|
||||
<div class="pickup-addr">员工餐厅一楼东侧 · 距您 200m</div>
|
||||
<div class="pickup-time">可取时段:11:00-13:00 / 17:00-19:00</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="order-detail">
|
||||
<div class="od-title">订单详情</div>
|
||||
<div class="order-item"><span class="oi-name">宫保鸡丁 ×1</span><span class="oi-price">¥12</span></div>
|
||||
<div class="order-item"><span class="oi-name">炒西兰花 ×1</span><span class="oi-price">¥8</span></div>
|
||||
<div class="order-item"><span class="oi-name">清蒸鱼 ×1</span><span class="oi-price">¥18</span></div>
|
||||
<div class="order-total"><span class="label">合计</span><span class="amount">¥38.00</span></div>
|
||||
<div id="orderItems">
|
||||
<div class="order-item"><span class="oi-name">宫保鸡丁 ×1</span><span class="oi-price">¥12</span></div>
|
||||
<div class="order-item"><span class="oi-name">炒西兰花 ×1</span><span class="oi-price">¥8</span></div>
|
||||
<div class="order-item"><span class="oi-name">清蒸鱼 ×1</span><span class="oi-price">¥18</span></div>
|
||||
</div>
|
||||
<div class="order-total"><span class="label">合计</span><span class="amount" id="orderAmount">¥38.00</span></div>
|
||||
</div>
|
||||
<div class="action-btns">
|
||||
<div class="action-btns" id="actionBtns">
|
||||
<a class="btn btn-ghost" href="eat-home.html">返回首页</a>
|
||||
<a class="btn btn-primary" href="me-orders.html">查看订单</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
<script>
|
||||
/* 解析 URL type 参数,渲染对应订单类型 */
|
||||
function getQuery(name) {
|
||||
var m = new RegExp('[?&]' + name + '=([^&]*)').exec(location.search);
|
||||
return m ? decodeURIComponent(m[1]) : '';
|
||||
}
|
||||
|
||||
var type = getQuery('type') === 'clean' ? 'clean' : 'meal';
|
||||
var successIcon = document.getElementById('successIcon');
|
||||
var successTitle = document.getElementById('successTitle');
|
||||
var successDesc = document.getElementById('successDesc');
|
||||
var pickupBlock = document.getElementById('pickupBlock');
|
||||
var fulfillBlock = document.getElementById('fulfillBlock');
|
||||
var orderItems = document.getElementById('orderItems');
|
||||
var orderAmount = document.getElementById('orderAmount');
|
||||
var actionBtns = document.getElementById('actionBtns');
|
||||
|
||||
/* 取货方式切换:联动地址组/自提组显示 */
|
||||
document.querySelectorAll('.pickup-method').forEach(function(m) {
|
||||
m.addEventListener('click', function() {
|
||||
document.querySelectorAll('.pickup-method').forEach(function(x) { x.classList.remove('active'); });
|
||||
m.classList.add('active');
|
||||
var isDelivery = m.dataset.method === 'delivery';
|
||||
document.getElementById('addressGroup').classList.toggle('hidden', !isDelivery);
|
||||
document.getElementById('pickupGroup').classList.toggle('hidden', isDelivery);
|
||||
});
|
||||
});
|
||||
|
||||
/* 日期 chip 单选切换 */
|
||||
document.querySelectorAll('.date-chip').forEach(function(c) {
|
||||
c.addEventListener('click', function() {
|
||||
document.querySelectorAll('.date-chip').forEach(function(x) { x.classList.remove('active'); });
|
||||
c.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
/* 时段 chip 单选切换 */
|
||||
document.querySelectorAll('.time-chip').forEach(function(c) {
|
||||
c.addEventListener('click', function() {
|
||||
document.querySelectorAll('.time-chip').forEach(function(x) { x.classList.remove('active'); });
|
||||
c.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
/* 收货地址:切换列表显示 */
|
||||
var addrSwitchBtn = document.getElementById('addrSwitchBtn');
|
||||
var addrList = document.getElementById('addrList');
|
||||
var addrForm = document.getElementById('addrForm');
|
||||
var addrCard = document.getElementById('addressCard');
|
||||
var addrName = document.getElementById('addrName');
|
||||
var addrPhone = document.getElementById('addrPhone');
|
||||
var addrDetail = document.getElementById('addrDetail');
|
||||
var addrDefaultTag = document.getElementById('addrDefaultTag');
|
||||
|
||||
addrSwitchBtn.addEventListener('click', function(e) {
|
||||
e.stopPropagation();
|
||||
var isOpen = addrList.classList.toggle('show');
|
||||
addrForm.classList.remove('show');
|
||||
addrSwitchBtn.textContent = isOpen ? '收起 ▴' : '切换 ›';
|
||||
});
|
||||
|
||||
/* 地址列表:选择切换 */
|
||||
addrList.addEventListener('click', function(e) {
|
||||
/* 点击新增按钮 */
|
||||
if (e.target.closest('#addrAddBtn')) {
|
||||
addrList.classList.remove('show');
|
||||
addrForm.classList.add('show');
|
||||
addrSwitchBtn.textContent = '切换 ›';
|
||||
return;
|
||||
}
|
||||
/* 点击某个地址 */
|
||||
var opt = e.target.closest('.addr-option');
|
||||
if (!opt) return;
|
||||
addrList.querySelectorAll('.addr-option').forEach(function(o) {
|
||||
o.classList.remove('active');
|
||||
/* 移除可能的默认标记徽标 */
|
||||
var oldTag = o.querySelector('.opt-default');
|
||||
if (oldTag) oldTag.remove();
|
||||
});
|
||||
opt.classList.add('active');
|
||||
/* 同步顶部卡片信息 */
|
||||
addrName.textContent = opt.dataset.name;
|
||||
addrPhone.textContent = opt.dataset.phone;
|
||||
addrDetail.textContent = opt.dataset.detail;
|
||||
var isDefault = opt.dataset.default === '1';
|
||||
if (isDefault) {
|
||||
addrDefaultTag.style.display = '';
|
||||
} else {
|
||||
addrDefaultTag.style.display = 'none';
|
||||
}
|
||||
/* 折叠列表 */
|
||||
addrList.classList.remove('show');
|
||||
addrSwitchBtn.textContent = '切换 ›';
|
||||
});
|
||||
|
||||
/* 新增地址:默认开关切换 */
|
||||
var addrDefaultToggle = document.getElementById('addrDefaultToggle');
|
||||
addrDefaultToggle.addEventListener('click', function() {
|
||||
addrDefaultToggle.classList.toggle('on');
|
||||
});
|
||||
|
||||
/* 新增地址:取消 */
|
||||
document.getElementById('addrCancelBtn').addEventListener('click', function() {
|
||||
addrForm.classList.remove('show');
|
||||
addrList.classList.add('show');
|
||||
addrSwitchBtn.textContent = '收起 ▴';
|
||||
});
|
||||
|
||||
/* 新增地址:保存(原型演示:直接回到列表) */
|
||||
document.getElementById('addrSaveBtn').addEventListener('click', function() {
|
||||
addrForm.classList.remove('show');
|
||||
addrList.classList.add('show');
|
||||
addrSwitchBtn.textContent = '收起 ▴';
|
||||
});
|
||||
|
||||
if (type === 'clean') {
|
||||
/* 净菜包订单:改为"确认订单"页,隐藏取餐码,展示履约表单 */
|
||||
successIcon.textContent = '📝';
|
||||
successTitle.textContent = '确认订单信息';
|
||||
successDesc.textContent = '请补充履约信息后提交订单';
|
||||
pickupBlock.classList.add('hidden');
|
||||
fulfillBlock.classList.remove('hidden');
|
||||
orderItems.innerHTML =
|
||||
'<div class="order-item"><span class="oi-name">宫保鸡丁净菜包 ×2</span><span class="oi-price">¥44</span></div>'
|
||||
+ '<div class="order-item"><span class="oi-name">低脂控糖套餐净菜包 ×1</span><span class="oi-price">¥35</span></div>';
|
||||
orderAmount.textContent = '¥79.00';
|
||||
/* 底部按钮:从"返回首页/查看订单"改为"返回购物车/确认下单" */
|
||||
actionBtns.innerHTML =
|
||||
'<a class="btn btn-ghost" href="eat-cart.html?type=clean">返回购物车</a>'
|
||||
+ '<a class="btn btn-primary" href="me-orders.html">确认下单(¥79.00)</a>';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -32,7 +32,23 @@
|
||||
.page-content { flex: 1; overflow-y: auto; background: #f5f5f5; }
|
||||
.page-content::-webkit-scrollbar { display: none; }
|
||||
/* 业务样式 */
|
||||
/* 订单类型 Tab:餐品 / 餐品净菜包 */
|
||||
.type-tabs { display: flex; background: #fff; border-bottom: 0.5px solid #f0f0f0; padding: 0 16px; flex-shrink: 0; }
|
||||
.type-tab {
|
||||
flex: 1; text-align: center; padding: 12px 0; font-size: 14px; color: #666;
|
||||
position: relative; cursor: pointer; display: flex; align-items: center; justify-content: center; gap: 4px;
|
||||
}
|
||||
.type-tab.active { color: #1677ff; font-weight: 600; }
|
||||
.type-tab.active::after {
|
||||
content: ''; position: absolute; bottom: 0; left: 30%; right: 30%; height: 2px;
|
||||
background: #1677ff; border-radius: 1px;
|
||||
}
|
||||
.type-tab .presale-tag {
|
||||
font-size: 10px; padding: 0 4px; background: #fff7e6; color: #fa8c16;
|
||||
border-radius: 3px; font-weight: 600;
|
||||
}
|
||||
.order-layout { display: flex; height: 100%; }
|
||||
.order-layout.hidden { display: none; }
|
||||
.category-sidebar {
|
||||
width: 80px; background: #f8f8f8; overflow-y: auto; flex-shrink: 0;
|
||||
}
|
||||
@@ -113,8 +129,14 @@
|
||||
<a class="back" href="javascript:history.back()">‹</a>
|
||||
<span class="title">订餐</span>
|
||||
</div>
|
||||
<!-- 订单类型 Tab:餐品(即时)/ 餐品净菜包(预售) -->
|
||||
<div class="type-tabs">
|
||||
<div class="type-tab active" data-type="meal">🍽️ 餐品</div>
|
||||
<div class="type-tab" data-type="clean">🥬 餐品净菜包 <span class="presale-tag">预售</span></div>
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<div class="order-layout">
|
||||
<!-- 餐品面板(即时点餐) -->
|
||||
<div class="order-layout" id="panel-meal">
|
||||
<!-- 左侧分类 -->
|
||||
<div class="category-sidebar">
|
||||
<div class="cat-item active">热菜</div>
|
||||
@@ -200,10 +222,95 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 餐品净菜包面板(预售,需选配送时间+取货方式) -->
|
||||
<div class="order-layout hidden" id="panel-clean">
|
||||
<!-- 左侧分类 -->
|
||||
<div class="category-sidebar">
|
||||
<div class="cat-item active">家常热菜</div>
|
||||
<div class="cat-item">健身轻食</div>
|
||||
<div class="cat-item">营养套餐</div>
|
||||
<div class="cat-item">家庭装</div>
|
||||
</div>
|
||||
<!-- 右侧净菜包列表 -->
|
||||
<div class="menu-area">
|
||||
<div class="menu-item" data-price="22">
|
||||
<div class="food-icon">🍗</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">宫保鸡丁净菜包</div>
|
||||
<div class="food-desc">腌好鸡丁+配料包 · 约300g · 285kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥22</span>
|
||||
<button class="add-btn">+</button>
|
||||
<div class="qty-ctrl"><button class="qty-btn minus">−</button><span class="qty-num">0</span><button class="qty-btn plus">+</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item" data-price="10">
|
||||
<div class="food-icon">🍅</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">番茄炒蛋净菜包</div>
|
||||
<div class="food-desc">切好番茄+调好蛋液 · 约250g · 168kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥10</span>
|
||||
<button class="add-btn">+</button>
|
||||
<div class="qty-ctrl"><button class="qty-btn minus">−</button><span class="qty-num">0</span><button class="qty-btn plus">+</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item" data-price="26">
|
||||
<div class="food-icon">🍖</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">红烧肉净菜包</div>
|
||||
<div class="food-desc">炖好五花肉+酱料包 · 约350g · 395kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥26</span>
|
||||
<button class="add-btn">+</button>
|
||||
<div class="qty-ctrl"><button class="qty-btn minus">−</button><span class="qty-num">0</span><button class="qty-btn plus">+</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item" data-price="28">
|
||||
<div class="food-icon">🐟</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">清蒸鱼净菜包</div>
|
||||
<div class="food-desc">处理净草鱼+葱姜丝 · 约220g · 142kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥28</span>
|
||||
<button class="add-btn">+</button>
|
||||
<div class="qty-ctrl"><button class="qty-btn minus">−</button><span class="qty-num">0</span><button class="qty-btn plus">+</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item" data-price="35">
|
||||
<div class="food-icon">🥗</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">低脂控糖套餐净菜包</div>
|
||||
<div class="food-desc">鸡胸+糙米饭+西兰花 · 约400g · 320kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥35</span>
|
||||
<button class="add-btn">+</button>
|
||||
<div class="qty-ctrl"><button class="qty-btn minus">−</button><span class="qty-num">0</span><button class="qty-btn plus">+</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="menu-item" data-price="68">
|
||||
<div class="food-icon">🍱</div>
|
||||
<div class="food-info">
|
||||
<div class="food-name">2-3人家庭套餐净菜包</div>
|
||||
<div class="food-desc">3菜1汤半成品 · 约1.2kg · 1200kcal</div>
|
||||
<div class="food-bottom">
|
||||
<span class="food-price">¥68</span>
|
||||
<button class="add-btn">+</button>
|
||||
<div class="qty-ctrl"><button class="qty-btn minus">−</button><span class="qty-num">0</span><button class="qty-btn plus">+</button></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 购物车栏 -->
|
||||
<div class="cart-bar">
|
||||
<a class="cart-icon-wrap" href="eat-cart.html" style="text-decoration:none">
|
||||
<a class="cart-icon-wrap" href="eat-cart.html?type=meal" style="text-decoration:none">
|
||||
<span style="font-size:20px">🛒</span>
|
||||
<span class="badge">3</span>
|
||||
</a>
|
||||
@@ -211,18 +318,36 @@
|
||||
<div class="cart-total">¥38.00</div>
|
||||
<div class="cart-desc">已选 3 个餐品</div>
|
||||
</div>
|
||||
<a href="eat-order-confirm.html" style="text-decoration:none"><button class="cart-submit">去结算</button></a>
|
||||
<a id="settleLink" href="eat-order-confirm.html?type=meal" style="text-decoration:none"><button class="cart-submit">去结算</button></a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
<script>
|
||||
/* 当前激活的订单类型:meal 餐品 / clean 餐品净菜包 */
|
||||
var currentType = 'meal';
|
||||
var badge = document.querySelector('.cart-icon-wrap .badge');
|
||||
var cartTotal = document.querySelector('.cart-total');
|
||||
var cartDesc = document.querySelector('.cart-desc');
|
||||
var cartLink = document.querySelector('.cart-icon-wrap');
|
||||
var settleLink = document.getElementById('settleLink');
|
||||
|
||||
/* 更新购物车栏 */
|
||||
/* 切换订单类型面板:联动分类、菜单、购物车/结算链接 */
|
||||
function switchType(type) {
|
||||
currentType = type;
|
||||
document.querySelectorAll('.type-tab').forEach(function(tab) {
|
||||
tab.classList.toggle('active', tab.dataset.type === type);
|
||||
});
|
||||
document.getElementById('panel-meal').classList.toggle('hidden', type !== 'meal');
|
||||
document.getElementById('panel-clean').classList.toggle('hidden', type !== 'clean');
|
||||
cartLink.href = 'eat-cart.html?type=' + type;
|
||||
settleLink.href = 'eat-order-confirm.html?type=' + type;
|
||||
updateCart();
|
||||
}
|
||||
|
||||
/* 更新购物车栏(仅统计当前激活面板) */
|
||||
function updateCart() {
|
||||
var items = document.querySelectorAll('.menu-item');
|
||||
var panel = document.getElementById('panel-' + currentType);
|
||||
var items = panel.querySelectorAll('.menu-item');
|
||||
var count = 0, total = 0;
|
||||
items.forEach(function(item) {
|
||||
var qty = parseInt(item.querySelector('.qty-num').textContent) || 0;
|
||||
@@ -233,10 +358,12 @@
|
||||
badge.textContent = count;
|
||||
badge.style.display = count > 0 ? 'flex' : 'none';
|
||||
cartTotal.textContent = '¥' + total.toFixed(2);
|
||||
cartDesc.textContent = '已选 ' + count + ' 个餐品';
|
||||
cartDesc.textContent = currentType === 'meal'
|
||||
? '已选 ' + count + ' 个餐品'
|
||||
: '已选 ' + count + ' 份净菜包';
|
||||
}
|
||||
|
||||
/* 点击 + 添加按钮 */
|
||||
/* 点击 + 添加按钮(两个面板通用) */
|
||||
document.querySelectorAll('.add-btn').forEach(function(btn) {
|
||||
btn.addEventListener('click', function() {
|
||||
var bottom = btn.closest('.food-bottom');
|
||||
@@ -249,7 +376,7 @@
|
||||
});
|
||||
});
|
||||
|
||||
/* 点击数量控制 +/- */
|
||||
/* 点击数量控制 +/-(两个面板通用) */
|
||||
document.querySelectorAll('.qty-ctrl').forEach(function(ctrl) {
|
||||
var plusBtn = ctrl.querySelector('.plus');
|
||||
var minusBtn = ctrl.querySelector('.minus');
|
||||
@@ -275,14 +402,22 @@
|
||||
});
|
||||
});
|
||||
|
||||
/* 左侧分类切换 */
|
||||
/* 左侧分类切换(在所属 sidebar 范围内切换 active) */
|
||||
document.querySelectorAll('.cat-item').forEach(function(cat) {
|
||||
cat.addEventListener('click', function() {
|
||||
document.querySelectorAll('.cat-item').forEach(function(c) { c.classList.remove('active'); });
|
||||
var sidebar = cat.closest('.category-sidebar');
|
||||
sidebar.querySelectorAll('.cat-item').forEach(function(c) { c.classList.remove('active'); });
|
||||
cat.classList.add('active');
|
||||
});
|
||||
});
|
||||
|
||||
/* 类型 Tab 切换 */
|
||||
document.querySelectorAll('.type-tab').forEach(function(tab) {
|
||||
tab.addEventListener('click', function() {
|
||||
switchType(tab.dataset.type);
|
||||
});
|
||||
});
|
||||
|
||||
/* 初始化:购物车归零 */
|
||||
updateCart();
|
||||
</script>
|
||||
|
||||
@@ -402,7 +402,7 @@
|
||||
<a class="tab-item active" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -151,7 +151,7 @@
|
||||
<!-- 快捷操作 -->
|
||||
<div class="quick-actions">
|
||||
<a class="quick-btn" style="background:linear-gradient(135deg,#1677ff,#4096ff)" href="eat-order.html"><span class="qicon">📷</span>扫码点餐</a>
|
||||
<a class="quick-btn" style="background:linear-gradient(135deg,#52c41a,#73d13d)" href="eat-order.html"><span class="qicon">🛒</span>订餐</a>
|
||||
<a class="quick-btn" style="background:linear-gradient(135deg,#52c41a,#73d13d)" href="eat-order.html"><span class="qicon">🛒</span>订餐/净菜</a>
|
||||
<a class="quick-btn" style="background:linear-gradient(135deg,#722ed1,#9254de)" href="eat-recipe-today.html"><span class="qicon">📋</span>查看食谱</a>
|
||||
</div>
|
||||
<!-- 推荐食谱列表 -->
|
||||
@@ -190,7 +190,7 @@
|
||||
<a class="tab-item active" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
<a class="tab-item" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item active" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -235,7 +235,7 @@
|
||||
<a class="tab-item" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item active" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -224,7 +224,7 @@
|
||||
<a class="tab-item" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item active" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -23,19 +23,27 @@
|
||||
.home-indicator { height: 20px; display: flex; align-items: center; justify-content: center; background: #fff; flex-shrink: 0; }
|
||||
.home-indicator::after { content: ''; width: 120px; height: 5px; background: #1a1a1a; border-radius: 3px; opacity: 0.2; }
|
||||
/* 用户卡片 */
|
||||
.profile-card { background: #fff; padding: 20px 16px; margin-bottom: 8px; display: flex; align-items: center; gap: 14px; }
|
||||
.profile-card .avatar { width: 56px; height: 56px; border-radius: 50%; background: linear-gradient(135deg,#e6f4ff,#bae0ff); display: flex; align-items: center; justify-content: center; font-size: 28px; }
|
||||
.profile-card { background: #fff; padding: 16px; margin-bottom: 8px; display: flex; align-items: center; gap: 12px; }
|
||||
.profile-card .avatar { width: 48px; height: 48px; border-radius: 50%; background: linear-gradient(135deg,#e6f4ff,#bae0ff); display: flex; align-items: center; justify-content: center; font-size: 24px; }
|
||||
.profile-card .info { flex: 1; }
|
||||
.profile-card .info .name { font-size: 16px; font-weight: 600; margin-bottom: 4px; }
|
||||
.profile-card .info .meta { font-size: 12px; color: #999; }
|
||||
.profile-card .cat { font-size: 11px; padding: 3px 8px; border-radius: 10px; background: #fff7e6; color: #fa8c16; }
|
||||
/* 通用分区 */
|
||||
.section { background: #fff; margin-bottom: 8px; padding: 16px; }
|
||||
.sec-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
|
||||
.sec-header .sec-title { font-size: 14px; font-weight: 600; color: #333; }
|
||||
/* 身体指标 - 列表行 */
|
||||
.body-row {
|
||||
display: flex; align-items: center; justify-content: space-between;
|
||||
padding: 13px 0; border-bottom: 0.5px solid #f5f5f5; cursor: pointer;
|
||||
}
|
||||
.section { background: #fff; margin-bottom: 8px; padding: 14px 16px; }
|
||||
.sec-header { display: flex; align-items: center; justify-content: space-between; margin-bottom: 10px; }
|
||||
.sec-header .sec-title { font-size: 14px; font-weight: 600; color: #333; display: flex; align-items: center; gap: 6px; }
|
||||
.sec-header .sec-title .sec-icon { font-size: 16px; }
|
||||
.sec-header .sec-action { font-size: 12px; color: #1677ff; cursor: pointer; }
|
||||
.sec-header .sec-action.readonly { color: #999; }
|
||||
/* 只读信息行 */
|
||||
.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; }
|
||||
/* 身体指标 - 列表行(可编辑) */
|
||||
.body-row { display: flex; align-items: center; justify-content: space-between; padding: 11px 0; border-bottom: 0.5px solid #f5f5f5; cursor: pointer; }
|
||||
.body-row:last-child { border-bottom: none; }
|
||||
.body-row .b-label { font-size: 14px; color: #333; }
|
||||
.body-row .b-right { display: flex; align-items: center; gap: 4px; }
|
||||
@@ -48,29 +56,52 @@
|
||||
.tag { padding: 5px 12px; border-radius: 14px; font-size: 12px; background: #f0f7ff; color: #1677ff; }
|
||||
.tag.warn { background: #fff7e6; color: #fa8c16; }
|
||||
.tag.danger { background: #fff1f0; color: #f5222d; }
|
||||
.tag-add { padding: 5px 12px; border-radius: 14px; font-size: 12px; background: #fafafa; color: #999; border: 1px dashed #d9d9d9; cursor: pointer; }
|
||||
/* 疾病信息列表 */
|
||||
.disease-list { }
|
||||
.disease-item { padding: 12px 0; border-bottom: 0.5px solid #f0f0f0; }
|
||||
.tag.orange { background: #fff7e6; color: #fa8c16; }
|
||||
/* 疾病信息 */
|
||||
.disease-item { padding: 10px 0; border-bottom: 0.5px solid #f0f0f0; }
|
||||
.disease-item:last-child { border-bottom: none; }
|
||||
.disease-item .d-label { font-size: 12px; color: #999; margin-bottom: 6px; }
|
||||
.disease-item .d-tags { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||
.disease-item .d-tag { padding: 4px 10px; border-radius: 12px; font-size: 12px; background: #fff1f0; color: #f5222d; }
|
||||
.disease-item .d-tag.med { background: #f0f7ff; color: #1677ff; }
|
||||
.disease-item .d-empty { font-size: 12px; color: #ccc; }
|
||||
/* 菜品偏好 */
|
||||
.dish-block { padding: 10px 0; border-bottom: 0.5px solid #f0f0f0; }
|
||||
.dish-block:last-child { border-bottom: none; }
|
||||
.dish-block .d-label { font-size: 12px; color: #999; margin-bottom: 8px; }
|
||||
.dish-block .dish-tags { display: flex; flex-wrap: wrap; gap: 6px; }
|
||||
.dish-block .dish-tag { padding: 4px 10px; border-radius: 12px; font-size: 12px; background: #f0f7ff; color: #1677ff; }
|
||||
.dish-block .dish-tag.rec { background: #f6ffed; color: #52c41a; }
|
||||
.dish-block .dish-big { font-size: 13px; color: #fa8c16; font-weight: 600; }
|
||||
.dish-block .dish-big.green { color: #52c41a; }
|
||||
.dish-block .dish-text { font-size: 13px; color: #666; }
|
||||
/* 妈妈味道 */
|
||||
.mom-hero { display: flex; align-items: center; gap: 10px; padding: 8px 0; }
|
||||
.mom-hero .mom-icon { width: 36px; height: 36px; border-radius: 10px; background: #fff7e6; display: flex; align-items: center; justify-content: center; font-size: 18px; }
|
||||
.mom-hero .mom-info .mom-title { font-size: 14px; font-weight: 600; color: #333; }
|
||||
.mom-hero .mom-info .mom-sub { font-size: 11px; color: #999; margin-top: 2px; }
|
||||
.mom-tags { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0; }
|
||||
.mom-tags .mom-tag { padding: 4px 10px; border-radius: 12px; font-size: 12px; background: #fff7e6; color: #fa8c16; }
|
||||
.mom-block { padding: 8px 0; border-bottom: 0.5px solid #f0f0f0; }
|
||||
.mom-block:last-child { border-bottom: none; }
|
||||
.mom-block .m-label { font-size: 12px; color: #999; margin-bottom: 6px; }
|
||||
.mom-block .m-text { font-size: 13px; color: #333; line-height: 1.5; }
|
||||
.mom-block .m-text.green { color: #52c41a; font-weight: 600; }
|
||||
/* 营养目标 */
|
||||
.goal-item { display: flex; align-items: center; justify-content: space-between; padding: 10px 0; border-bottom: 0.5px solid #f0f0f0; }
|
||||
.goal-item:last-child { border-bottom: none; }
|
||||
.goal-item .g-label { font-size: 13px; color: #333; }
|
||||
.goal-item .g-value { font-size: 13px; color: #1677ff; font-weight: 600; }
|
||||
/* 体检报告入口 */
|
||||
.exam-entry { margin-top: 12px; padding: 10px 12px; background: #f5f5f5; border-radius: 10px; display: flex; align-items: center; justify-content: space-between; cursor: pointer; }
|
||||
.exam-entry .e-left { display: flex; align-items: center; gap: 6px; font-size: 13px; color: #333; }
|
||||
.exam-entry .e-arrow { font-size: 14px; color: #ccc; }
|
||||
/* ========== 编辑弹窗通用样式 ========== */
|
||||
/* 遮罩层:覆盖整个 phone-shell */
|
||||
.modal-mask {
|
||||
position: absolute; inset: 0; background: rgba(0,0,0,0.45);
|
||||
display: none; align-items: flex-end; justify-content: center; z-index: 50;
|
||||
}
|
||||
.modal-mask.active { display: flex; }
|
||||
/* 弹窗容器:底部弹出 */
|
||||
.modal-panel {
|
||||
width: 100%; max-height: 80%; background: #fff;
|
||||
border-top-left-radius: 16px; border-top-right-radius: 16px;
|
||||
@@ -85,9 +116,9 @@
|
||||
.modal-header .m-save { font-size: 14px; color: #1677ff; font-weight: 600; cursor: pointer; }
|
||||
.modal-body { padding: 12px 16px 8px; overflow-y: auto; flex: 1; }
|
||||
.modal-body::-webkit-scrollbar { display: none; }
|
||||
/* 弹窗中分组 */
|
||||
.m-group { margin-bottom: 16px; }
|
||||
.m-group .m-g-label { font-size: 13px; color: #666; font-weight: 500; margin-bottom: 8px; }
|
||||
.m-group .m-g-hint { font-size: 11px; color: #bbb; margin-top: 4px; }
|
||||
/* 可编辑的标签列表(带 × 删除) */
|
||||
.m-tag-list { display: flex; flex-wrap: wrap; gap: 8px; }
|
||||
.m-tag {
|
||||
@@ -96,13 +127,13 @@
|
||||
background: #fff1f0; color: #f5222d;
|
||||
}
|
||||
.m-tag.med { background: #f0f7ff; color: #1677ff; }
|
||||
.m-tag.warn { background: #fff7e6; color: #fa8c16; }
|
||||
.m-tag .m-del {
|
||||
width: 16px; height: 16px; border-radius: 50%;
|
||||
background: rgba(0,0,0,0.08); color: #666;
|
||||
display: flex; align-items: center; justify-content: center;
|
||||
font-size: 12px; line-height: 1; cursor: pointer; font-weight: 700;
|
||||
}
|
||||
/* 添加输入区 */
|
||||
.m-add-row { display: flex; gap: 8px; margin-top: 10px; }
|
||||
.m-add-row input {
|
||||
flex: 1; height: 32px; border: 1px solid #e5e5e5; border-radius: 16px;
|
||||
@@ -128,6 +159,19 @@
|
||||
}
|
||||
.m-goal-row input:focus { border-color: #1677ff; }
|
||||
.m-goal-row .mg-unit { font-size: 12px; color: #999; min-width: 36px; }
|
||||
/* 通用文本输入(妈妈味道/菜品偏好) */
|
||||
.m-input {
|
||||
width: 100%; height: 36px; border: 1px solid #e5e5e5; border-radius: 8px;
|
||||
padding: 0 12px; font-size: 13px; outline: none; background: #fafafa;
|
||||
margin-top: 6px;
|
||||
}
|
||||
.m-input:focus { border-color: #1677ff; background: #fff; }
|
||||
.m-textarea {
|
||||
width: 100%; min-height: 64px; border: 1px solid #e5e5e5; border-radius: 8px;
|
||||
padding: 8px 12px; font-size: 13px; outline: none; background: #fafafa;
|
||||
margin-top: 6px; resize: none; line-height: 1.5; font-family: inherit;
|
||||
}
|
||||
.m-textarea:focus { border-color: #1677ff; background: #fff; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -146,55 +190,64 @@
|
||||
<div class="avatar">👤</div>
|
||||
<div class="info">
|
||||
<div class="name">张三</div>
|
||||
<div class="meta">男 · 32岁 · 172cm · 68kg</div>
|
||||
<div class="meta">男 · 32岁 · 公司机关/研发部</div>
|
||||
</div>
|
||||
<span class="cat">会员用户</span>
|
||||
</div>
|
||||
<!-- 身体指标 -->
|
||||
<div class="section">
|
||||
<div class="sec-header"><span class="sec-title">身体指标</span></div>
|
||||
<div class="body-row" onclick="alert('【交互注释】编辑身高')">
|
||||
|
||||
<!-- 1. 身体指标(静态基础)可编辑 -->
|
||||
<div class="section" id="bodySection" onclick="openBodyModal()" style="cursor:pointer;">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">📏</span>身体指标</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="body-row">
|
||||
<span class="b-label">身高</span>
|
||||
<span class="b-right"><span class="b-val">172</span><span class="b-unit">cm</span><span class="b-arrow">›</span></span>
|
||||
<span class="b-right"><span class="b-val" id="viewBodyHeight">172</span><span class="b-unit">cm</span></span>
|
||||
</div>
|
||||
<div class="body-row" onclick="alert('【交互注释】编辑体重')">
|
||||
<div class="body-row">
|
||||
<span class="b-label">体重</span>
|
||||
<span class="b-right"><span class="b-val">68</span><span class="b-unit">kg</span><span class="b-arrow">›</span></span>
|
||||
<span class="b-right"><span class="b-val" id="viewBodyWeight">68</span><span class="b-unit">kg</span></span>
|
||||
</div>
|
||||
<div class="body-row" onclick="alert('【交互注释】查看BMI详情')">
|
||||
<div class="body-row">
|
||||
<span class="b-label">BMI</span>
|
||||
<span class="b-right"><span class="b-val">23.0</span><span class="b-tag">正常</span><span class="b-arrow">›</span></span>
|
||||
<span class="b-right"><span class="b-val" id="viewBodyBmi">23.0</span><span class="b-tag">正常</span></span>
|
||||
</div>
|
||||
<div class="body-row" onclick="alert('【交互注释】编辑体脂率')">
|
||||
<div class="body-row">
|
||||
<span class="b-label">体脂率</span>
|
||||
<span class="b-right"><span class="b-val">18.5%</span><span class="b-tag">标准</span><span class="b-arrow">›</span></span>
|
||||
<span class="b-right"><span class="b-val" id="viewBodyFat">18.5%</span><span class="b-tag">标准</span></span>
|
||||
</div>
|
||||
<div class="body-row" onclick="alert('【交互注释】编辑活动水平')">
|
||||
<div class="body-row">
|
||||
<span class="b-label">活动水平</span>
|
||||
<span class="b-right"><span class="b-val">中等</span><span class="b-unit">每周3-5次</span><span class="b-arrow">›</span></span>
|
||||
<span class="b-right"><span class="b-val" id="viewBodyActivity">中度活动</span><span class="b-unit">每周3-5次</span></span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 过敏信息 -->
|
||||
<div class="section" onclick="alert('【交互注释】进入过敏信息编辑页')" style="cursor:pointer;">
|
||||
<div class="sec-header"><span class="sec-title">过敏信息</span><span style="font-size:14px;color:#ccc;">›</span></div>
|
||||
<div class="tag-list">
|
||||
<span class="tag warn">🥜 花生过敏</span>
|
||||
<span class="tag warn">🦐 海鲜过敏</span>
|
||||
<span class="tag-add">+ 添加</span>
|
||||
|
||||
<!-- 2. 体检信息 只读 -->
|
||||
<div class="section">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">🩺</span>体检信息</span>
|
||||
<span class="sec-action readonly">只读</span>
|
||||
</div>
|
||||
<div class="info-row"><span class="i-label">体检日期</span><span class="i-value" id="viewExamDate">2026-03-15</span></div>
|
||||
<div class="info-row"><span class="i-label">血压</span><span class="i-value" id="viewExamBp">125/80<span class="i-unit">mmHg</span></span></div>
|
||||
<div class="info-row"><span class="i-label">空腹血糖</span><span class="i-value" id="viewExamGlucose">5.2<span class="i-unit">mmol/L</span></span></div>
|
||||
<div class="info-row"><span class="i-label">血脂</span><span class="i-value" id="viewExamLipid">正常</span></div>
|
||||
<div class="info-row"><span class="i-label">尿酸</span><span class="i-value" id="viewExamUric">380<span class="i-unit">μmol/L</span></span></div>
|
||||
<div class="info-row"><span class="i-label">肝功能</span><span class="i-value" id="viewExamLiver">正常</span></div>
|
||||
<div class="info-row"><span class="i-label">肾功能</span><span class="i-value" id="viewExamKidney">正常</span></div>
|
||||
<div class="exam-entry" onclick="alert('【交互注释】查看体检报告,功能暂未开放')">
|
||||
<span class="e-left">📎 查看体检报告</span>
|
||||
<span class="e-arrow">›</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 饮食禁忌 -->
|
||||
<div class="section" onclick="alert('【交互注释】进入饮食禁忌编辑页')" style="cursor:pointer;">
|
||||
<div class="sec-header"><span class="sec-title">饮食禁忌</span><span style="font-size:14px;color:#ccc;">›</span></div>
|
||||
<div class="tag-list">
|
||||
<span class="tag">🌶️ 少辣</span>
|
||||
<span class="tag">🧂 低盐</span>
|
||||
<span class="tag">🍬 控糖</span>
|
||||
<span class="tag-add">+ 添加</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 疾病信息 -->
|
||||
|
||||
<!-- 3. 疾病信息 可编辑 -->
|
||||
<div class="section" id="diseaseSection" onclick="openDiseaseModal()" style="cursor:pointer;">
|
||||
<div class="sec-header"><span class="sec-title">疾病信息</span><span style="font-size:14px;color:#ccc;">›</span></div>
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">🏥</span>疾病信息</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="disease-list">
|
||||
<div class="disease-item">
|
||||
<div class="d-label">疾病史</div>
|
||||
@@ -203,6 +256,12 @@
|
||||
<span class="d-tag">高尿酸</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="disease-item">
|
||||
<div class="d-label">用药情况</div>
|
||||
<div class="d-tags" id="viewMedications">
|
||||
<span class="d-tag med">别嘌醇片</span><span class="d-tag med">依那普利</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="disease-item">
|
||||
<div class="d-label">家族病史</div>
|
||||
<div class="d-tags" id="viewFamilyHistory">
|
||||
@@ -210,17 +269,124 @@
|
||||
<span class="d-tag">糖尿病</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="disease-item">
|
||||
<div class="d-label">用药情况</div>
|
||||
<div class="d-tags" id="viewMedications">
|
||||
<span class="d-tag med">别嘌醇片</span><span class="d-tag med">依那普利</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 4. 口味偏好 可编辑 -->
|
||||
<div class="section" id="tasteSection" onclick="openTasteModal()" style="cursor:pointer;">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">👅</span>口味偏好</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="dish-block" style="padding:8px 0;">
|
||||
<div class="d-label">口味偏好</div>
|
||||
<div class="dish-tags" id="viewTasteList">
|
||||
<span class="tag">偏辣</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dish-block" style="padding:8px 0;">
|
||||
<div class="d-label">地域菜系</div>
|
||||
<div class="dish-tags" id="viewRegionList">
|
||||
<span class="tag">川菜</span>
|
||||
<span class="tag">湘菜</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 营养目标 -->
|
||||
|
||||
<!-- 5. 禁忌关联(饮食禁忌 + 过敏原)可编辑 -->
|
||||
<div class="section" id="tabooSection" onclick="openTabooModal()" style="cursor:pointer;">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">🚫</span>禁忌关联</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="dish-block" style="padding:8px 0;">
|
||||
<div class="d-label">饮食禁忌</div>
|
||||
<div class="dish-tags" id="viewTabooList">
|
||||
<span class="tag">🌶️ 少辣</span>
|
||||
<span class="tag">🧂 低盐</span>
|
||||
<span class="tag">🍬 控糖</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dish-block" style="padding:8px 0;">
|
||||
<div class="d-label">过敏原</div>
|
||||
<div class="dish-tags" id="viewAllergyList">
|
||||
<span class="tag warn">🥜 花生</span>
|
||||
<span class="tag warn">🦐 海鲜</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 6. 动态生理 只读 -->
|
||||
<div class="section">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">📊</span>动态生理</span>
|
||||
<span class="sec-action readonly">只读</span>
|
||||
</div>
|
||||
<div class="info-row"><span class="i-label">日均运动量</span><span class="i-value" id="viewExercise">6000步/日</span></div>
|
||||
<div class="info-row"><span class="i-label">静息心率</span><span class="i-value" id="viewHeartRate">68<span class="i-unit">bpm</span></span></div>
|
||||
<div class="info-row"><span class="i-label">平均睡眠</span><span class="i-value" id="viewSleep">7.5h</span></div>
|
||||
<div class="info-row"><span class="i-label">压力指数</span><span class="i-value" id="viewStress">低</span></div>
|
||||
<div class="info-row"><span class="i-label">数据来源</span><span class="i-value" id="viewSource">智能手环</span></div>
|
||||
</div>
|
||||
|
||||
<!-- 7. 菜品偏好 可编辑 -->
|
||||
<div class="section" id="dishSection" onclick="openDishModal()" style="cursor:pointer;">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">🍲</span>菜品偏好</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="dish-block">
|
||||
<div class="d-label">常点菜品</div>
|
||||
<div class="dish-tags" id="viewFavDish">
|
||||
<span class="dish-tag">宫保鸡丁</span>
|
||||
<span class="dish-tag">清炒西兰花</span>
|
||||
<span class="dish-tag">杂粮饭</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="dish-block">
|
||||
<div class="d-label">忌口菜品</div>
|
||||
<div class="dish-text" id="viewAvoidDish">油炸花生</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 8. 妈妈味道 可编辑 -->
|
||||
<div class="section" id="momSection" onclick="openMomModal()" style="cursor:pointer;">
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">🏡</span>妈妈味道</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="mom-hero">
|
||||
<div class="mom-icon">🏠</div>
|
||||
<div class="mom-info">
|
||||
<div class="mom-title" id="viewHometown">家乡:四川成都</div>
|
||||
<div class="mom-sub">从童年记忆中沉淀的味觉偏好</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mom-tags" id="viewMomTags">
|
||||
<span class="mom-tag">麻辣</span>
|
||||
<span class="mom-tag">红油</span>
|
||||
<span class="mom-tag">鲜香</span>
|
||||
</div>
|
||||
<div class="mom-block">
|
||||
<div class="m-label">思乡菜清单</div>
|
||||
<div class="dish-tags" id="viewMomList">
|
||||
<span class="dish-tag" style="background:#fff7e6;color:#fa8c16;">回锅肉</span>
|
||||
<span class="dish-tag" style="background:#fff7e6;color:#fa8c16;">麻婆豆腐</span>
|
||||
<span class="dish-tag" style="background:#fff7e6;color:#fa8c16;">水煮鱼</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mom-block">
|
||||
<div class="m-label">关联记忆</div>
|
||||
<div class="m-text" id="viewMemory">从小常吃妈妈做的回锅肉,奠定了麻辣口味偏好。</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 9. 营养目标 保留 -->
|
||||
<div class="section" id="goalSection" onclick="openGoalModal()" style="cursor:pointer;">
|
||||
<div class="sec-header"><span class="sec-title">营养目标</span><span style="font-size:14px;color:#ccc;">›</span></div>
|
||||
<div class="sec-header">
|
||||
<span class="sec-title"><span class="sec-icon">🎯</span>营养目标</span>
|
||||
<span class="sec-action">编辑 ›</span>
|
||||
</div>
|
||||
<div class="goal-item"><span class="g-label">每日热量</span><span class="g-value" id="viewGoalCalorie">2000 kcal</span></div>
|
||||
<div class="goal-item"><span class="g-label">蛋白质</span><span class="g-value" id="viewGoalProtein">≥60g</span></div>
|
||||
<div class="goal-item"><span class="g-label">膳食纤维</span><span class="g-value" id="viewGoalFiber">≥25g</span></div>
|
||||
@@ -229,42 +395,192 @@
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
|
||||
<!-- ========== 身体指标编辑弹窗 ========== -->
|
||||
<div class="modal-mask" id="bodyModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeModal('bodyModal')">取消</span>
|
||||
<span class="m-title">编辑身体指标</span>
|
||||
<span class="m-save" onclick="saveBodyModal()">保存</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="m-goal-row">
|
||||
<span class="mg-label">身高</span>
|
||||
<span class="mg-input-wrap"><input type="number" id="inputHeight" value="172"><span class="mg-unit">cm</span></span>
|
||||
</div>
|
||||
<div class="m-goal-row">
|
||||
<span class="mg-label">体重</span>
|
||||
<span class="mg-input-wrap"><input type="number" id="inputWeight" value="68"><span class="mg-unit">kg</span></span>
|
||||
</div>
|
||||
<div class="m-goal-row">
|
||||
<span class="mg-label">体脂率</span>
|
||||
<span class="mg-input-wrap"><input type="number" id="inputFat" value="18.5"><span class="mg-unit">%</span></span>
|
||||
</div>
|
||||
<div class="m-goal-row">
|
||||
<span class="mg-label">活动水平</span>
|
||||
<span class="mg-input-wrap"><input type="text" id="inputActivity" value="中度活动" style="width:120px;"><span class="mg-unit"></span></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 疾病信息编辑弹窗 ========== -->
|
||||
<div class="modal-mask" id="diseaseModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeDiseaseModal()">取消</span>
|
||||
<span class="m-cancel" onclick="closeModal('diseaseModal')">取消</span>
|
||||
<span class="m-title">编辑疾病信息</span>
|
||||
<span class="m-save" onclick="saveDiseaseModal()">保存</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<!-- 疾病史 -->
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">疾病史(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editDiseaseHistory"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputDiseaseHistory" placeholder="如:胃炎、高血压" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addDiseaseTag('editDiseaseHistory','inputDiseaseHistory')">添加</button>
|
||||
<button class="m-add-btn" onclick="addTag('editDiseaseHistory','inputDiseaseHistory','')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 家族病史 -->
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">家族病史(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editFamilyHistory"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputFamilyHistory" placeholder="如:糖尿病、冠心病" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addDiseaseTag('editFamilyHistory','inputFamilyHistory')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 用药情况 -->
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">用药情况(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editMedications"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputMedications" placeholder="如:别嘌醇片" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addDiseaseTag('editMedications','inputMedications')">添加</button>
|
||||
<button class="m-add-btn" onclick="addTag('editMedications','inputMedications','med')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">家族病史(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editFamilyHistory"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputFamilyHistory" placeholder="如:糖尿病、冠心病" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editFamilyHistory','inputFamilyHistory','')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 口味偏好编辑弹窗 ========== -->
|
||||
<div class="modal-mask" id="tasteModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeModal('tasteModal')">取消</span>
|
||||
<span class="m-title">编辑口味偏好</span>
|
||||
<span class="m-save" onclick="saveTasteModal()">保存</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">口味偏好(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editTasteList"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputTasteList" placeholder="如:偏辣、偏咸" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editTasteList','inputTasteList','')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">地域菜系(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editRegionList"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputRegionList" placeholder="如:川菜、粤菜" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editRegionList','inputRegionList','')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 禁忌关联编辑弹窗 ========== -->
|
||||
<div class="modal-mask" id="tabooModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeModal('tabooModal')">取消</span>
|
||||
<span class="m-title">编辑禁忌关联</span>
|
||||
<span class="m-save" onclick="saveTabooModal()">保存</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">饮食禁忌</div>
|
||||
<div class="m-tag-list" id="editTabooList"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputTabooList" placeholder="如:少辣、低盐" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editTabooList','inputTabooList','warn')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">过敏原</div>
|
||||
<div class="m-tag-list" id="editAllergyList"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputAllergyList" placeholder="如:花生、海鲜" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editAllergyList','inputAllergyList','warn')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 菜品偏好编辑弹窗 ========== -->
|
||||
<div class="modal-mask" id="dishModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeModal('dishModal')">取消</span>
|
||||
<span class="m-title">编辑菜品偏好</span>
|
||||
<span class="m-save" onclick="saveDishModal()">保存</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">常点菜品(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editFavDish"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputFavDish" placeholder="如:宫保鸡丁" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editFavDish','inputFavDish','med')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">忌口菜品(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editAvoidDish"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputAvoidDish" placeholder="如:油炸花生" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editAvoidDish','inputAvoidDish','')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ========== 妈妈味道编辑弹窗 ========== -->
|
||||
<div class="modal-mask" id="momModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeModal('momModal')">取消</span>
|
||||
<span class="m-title">编辑妈妈味道</span>
|
||||
<span class="m-save" onclick="saveMomModal()">保存</span>
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">家乡</div>
|
||||
<input type="text" id="inputHometown" class="m-input" value="四川成都" placeholder="如:四川成都">
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">口味标签(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editMomTags"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputMomTags" placeholder="如:麻辣、鲜香" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editMomTags','inputMomTags','warn')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">思乡菜清单(可添加多个)</div>
|
||||
<div class="m-tag-list" id="editMomList"></div>
|
||||
<div class="m-add-row">
|
||||
<input type="text" id="inputMomList" placeholder="如:回锅肉" maxlength="20">
|
||||
<button class="m-add-btn" onclick="addTag('editMomList','inputMomList','warn')">添加</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="m-group">
|
||||
<div class="m-g-label">关联记忆</div>
|
||||
<textarea id="inputMemory" class="m-textarea" placeholder="记录与妈妈菜相关的童年记忆">从小常吃妈妈做的回锅肉,奠定了麻辣口味偏好。</textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -273,7 +589,7 @@
|
||||
<div class="modal-mask" id="goalModal">
|
||||
<div class="modal-panel" onclick="event.stopPropagation()">
|
||||
<div class="modal-header">
|
||||
<span class="m-cancel" onclick="closeGoalModal()">取消</span>
|
||||
<span class="m-cancel" onclick="closeModal('goalModal')">取消</span>
|
||||
<span class="m-title">编辑营养目标</span>
|
||||
<span class="m-save" onclick="saveGoalModal()">保存</span>
|
||||
</div>
|
||||
@@ -299,18 +615,30 @@
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
/* ========== 疾病信息编辑弹窗 ========== */
|
||||
// 当前编辑状态(页面初始数据;保存时同步回页面)
|
||||
var diseaseState = {
|
||||
/* ========== 通用弹窗控制 ========== */
|
||||
function closeModal(id) { document.getElementById(id).classList.remove('active'); }
|
||||
|
||||
/* ========== 通用标签编辑组件(替代旧版 diseaseState) ========== */
|
||||
// 编辑态数据:每个分组的标签数组 + 标签 css 类
|
||||
var editState = {
|
||||
editDiseaseHistory: { tags: ['胃炎', '高尿酸'], cls: '' },
|
||||
editFamilyHistory: { tags: ['高血压', '糖尿病'], cls: '' },
|
||||
editMedications: { tags: ['别嘌醇片', '依那普利'], cls: 'med' }
|
||||
editMedications: { tags: ['别嘌醇片', '依那普利'], cls: 'med' },
|
||||
editFamilyHistory: { tags: ['高血压', '糖尿病'], cls: '' },
|
||||
editTasteList: { tags: ['偏辣'], cls: '' },
|
||||
editRegionList: { tags: ['川菜', '湘菜'], cls: '' },
|
||||
editTabooList: { tags: ['🌶️ 少辣', '🧂 低盐', '🍬 控糖'], cls: 'warn' },
|
||||
editAllergyList: { tags: ['🥜 花生', '🦐 海鲜'], cls: 'warn' },
|
||||
editFavDish: { tags: ['宫保鸡丁', '清炒西兰花', '杂粮饭'], cls: 'med' },
|
||||
editAvoidDish: { tags: ['油炸花生'], cls: '' },
|
||||
editMomTags: { tags: ['麻辣', '红油', '鲜香'], cls: 'warn' },
|
||||
editMomList: { tags: ['回锅肉', '麻婆豆腐', '水煮鱼'], cls: 'warn' }
|
||||
};
|
||||
|
||||
// 渲染弹窗中某一组的标签列表(带 × 删除)
|
||||
function renderDiseaseGroup(groupId) {
|
||||
// 渲染某一分组的可编辑标签列表(带 × 删除)
|
||||
function renderGroup(groupId) {
|
||||
var box = document.getElementById(groupId);
|
||||
var state = diseaseState[groupId];
|
||||
var state = editState[groupId];
|
||||
if (!box || !state) return;
|
||||
box.innerHTML = '';
|
||||
state.tags.forEach(function(tag, idx) {
|
||||
var span = document.createElement('span');
|
||||
@@ -318,64 +646,126 @@
|
||||
span.innerHTML = tag + '<span class="m-del">×</span>';
|
||||
span.querySelector('.m-del').addEventListener('click', function() {
|
||||
state.tags.splice(idx, 1);
|
||||
renderDiseaseGroup(groupId);
|
||||
renderGroup(groupId);
|
||||
});
|
||||
box.appendChild(span);
|
||||
});
|
||||
}
|
||||
|
||||
// 添加一个新标签到指定分组
|
||||
function addDiseaseTag(groupId, inputId) {
|
||||
// 添加标签到指定分组
|
||||
function addTag(groupId, inputId, cls) {
|
||||
var input = document.getElementById(inputId);
|
||||
var val = (input.value || '').trim();
|
||||
if (!val) { alert('请输入内容'); return; }
|
||||
if (diseaseState[groupId].tags.indexOf(val) !== -1) { alert('该项已存在'); return; }
|
||||
diseaseState[groupId].tags.push(val);
|
||||
if (editState[groupId].tags.indexOf(val) !== -1) { alert('该项已存在'); return; }
|
||||
editState[groupId].tags.push(val);
|
||||
input.value = '';
|
||||
renderDiseaseGroup(groupId);
|
||||
renderGroup(groupId);
|
||||
}
|
||||
|
||||
// 打开疾病信息弹窗
|
||||
function openDiseaseModal() {
|
||||
renderDiseaseGroup('editDiseaseHistory');
|
||||
renderDiseaseGroup('editFamilyHistory');
|
||||
renderDiseaseGroup('editMedications');
|
||||
document.getElementById('diseaseModal').classList.add('active');
|
||||
}
|
||||
function closeDiseaseModal() {
|
||||
document.getElementById('diseaseModal').classList.remove('active');
|
||||
}
|
||||
// 保存:将编辑结果写回页面对应区块
|
||||
function saveDiseaseModal() {
|
||||
function syncBack(viewId, groupId) {
|
||||
var view = document.getElementById(viewId);
|
||||
var state = diseaseState[groupId];
|
||||
view.innerHTML = '';
|
||||
if (state.tags.length === 0) {
|
||||
view.innerHTML = '<span class="d-empty">暂无</span>';
|
||||
return;
|
||||
}
|
||||
state.tags.forEach(function(tag) {
|
||||
var s = document.createElement('span');
|
||||
s.className = 'd-tag' + (state.cls ? ' ' + state.cls : '');
|
||||
s.textContent = tag;
|
||||
view.appendChild(s);
|
||||
});
|
||||
}
|
||||
syncBack('viewDiseaseHistory', 'editDiseaseHistory');
|
||||
syncBack('viewFamilyHistory', 'editFamilyHistory');
|
||||
syncBack('viewMedications', 'editMedications');
|
||||
closeDiseaseModal();
|
||||
/* ========== 身体指标 ========== */
|
||||
function openBodyModal() { document.getElementById('bodyModal').classList.add('active'); }
|
||||
function saveBodyModal() {
|
||||
var h = document.getElementById('inputHeight').value || '0';
|
||||
var w = document.getElementById('inputWeight').value || '0';
|
||||
var fat = document.getElementById('inputFat').value || '0';
|
||||
var act = document.getElementById('inputActivity').value || '';
|
||||
var bmi = (parseFloat(w) / Math.pow(parseFloat(h) / 100, 2)).toFixed(1);
|
||||
document.getElementById('viewBodyHeight').textContent = h;
|
||||
document.getElementById('viewBodyWeight').textContent = w;
|
||||
document.getElementById('viewBodyBmi').textContent = (isNaN(bmi) ? '—' : bmi);
|
||||
document.getElementById('viewBodyFat').textContent = fat + '%';
|
||||
document.getElementById('viewBodyActivity').textContent = act;
|
||||
closeModal('bodyModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* ========== 营养目标编辑弹窗 ========== */
|
||||
function openGoalModal() {
|
||||
document.getElementById('goalModal').classList.add('active');
|
||||
/* ========== 疾病信息 ========== */
|
||||
function openDiseaseModal() {
|
||||
renderGroup('editDiseaseHistory');
|
||||
renderGroup('editMedications');
|
||||
renderGroup('editFamilyHistory');
|
||||
document.getElementById('diseaseModal').classList.add('active');
|
||||
}
|
||||
function closeGoalModal() {
|
||||
document.getElementById('goalModal').classList.remove('active');
|
||||
function saveDiseaseModal() {
|
||||
syncGroupBack('viewDiseaseHistory', 'editDiseaseHistory', 'd-tag');
|
||||
syncGroupBack('viewMedications', 'editMedications', 'd-tag med');
|
||||
syncGroupBack('viewFamilyHistory', 'editFamilyHistory', 'd-tag');
|
||||
closeModal('diseaseModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* ========== 口味偏好 ========== */
|
||||
function openTasteModal() {
|
||||
renderGroup('editTasteList');
|
||||
renderGroup('editRegionList');
|
||||
document.getElementById('tasteModal').classList.add('active');
|
||||
}
|
||||
function saveTasteModal() {
|
||||
syncGroupBack('viewTasteList', 'editTasteList', 'tag');
|
||||
syncGroupBack('viewRegionList','editRegionList', 'tag');
|
||||
closeModal('tasteModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* ========== 禁忌关联 ========== */
|
||||
function openTabooModal() {
|
||||
renderGroup('editTabooList');
|
||||
renderGroup('editAllergyList');
|
||||
document.getElementById('tabooModal').classList.add('active');
|
||||
}
|
||||
function saveTabooModal() {
|
||||
syncGroupBack('viewTabooList', 'editTabooList', 'tag');
|
||||
syncGroupBack('viewAllergyList', 'editAllergyList', 'tag warn');
|
||||
closeModal('tabooModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* ========== 菜品偏好 ========== */
|
||||
function openDishModal() {
|
||||
renderGroup('editFavDish');
|
||||
renderGroup('editAvoidDish');
|
||||
document.getElementById('dishModal').classList.add('active');
|
||||
}
|
||||
function saveDishModal() {
|
||||
syncGroupBack('viewFavDish', 'editFavDish', 'dish-tag');
|
||||
syncGroupBack('viewAvoidDish', 'editAvoidDish', 'dish-text', true);
|
||||
closeModal('dishModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* ========== 妈妈味道 ========== */
|
||||
function openMomModal() {
|
||||
renderGroup('editMomTags');
|
||||
renderGroup('editMomList');
|
||||
document.getElementById('momModal').classList.add('active');
|
||||
}
|
||||
function saveMomModal() {
|
||||
document.getElementById('viewHometown').textContent = '家乡:' + (document.getElementById('inputHometown').value || '—');
|
||||
// 口味标签
|
||||
var momTagsBox = document.getElementById('viewMomTags');
|
||||
momTagsBox.innerHTML = '';
|
||||
editState.editMomTags.tags.forEach(function(t) {
|
||||
var s = document.createElement('span'); s.className = 'mom-tag'; s.textContent = t;
|
||||
momTagsBox.appendChild(s);
|
||||
});
|
||||
// 思乡菜清单
|
||||
var momListBox = document.getElementById('viewMomList');
|
||||
momListBox.innerHTML = '';
|
||||
editState.editMomList.tags.forEach(function(t) {
|
||||
var s = document.createElement('span');
|
||||
s.className = 'dish-tag';
|
||||
s.setAttribute('style', 'background:#fff7e6;color:#fa8c16;');
|
||||
s.textContent = t;
|
||||
momListBox.appendChild(s);
|
||||
});
|
||||
document.getElementById('viewMemory').textContent = document.getElementById('inputMemory').value || '—';
|
||||
closeModal('momModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* ========== 营养目标 ========== */
|
||||
function openGoalModal() { document.getElementById('goalModal').classList.add('active'); }
|
||||
function saveGoalModal() {
|
||||
var cal = document.getElementById('inputCalorie').value || '0';
|
||||
var pro = document.getElementById('inputProtein').value || '0';
|
||||
@@ -383,15 +773,39 @@
|
||||
var wat = document.getElementById('inputWater').value || '0';
|
||||
document.getElementById('viewGoalCalorie').textContent = cal + ' kcal';
|
||||
document.getElementById('viewGoalProtein').textContent = '≥' + pro + 'g';
|
||||
document.getElementById('viewGoalFiber').textContent = '≥' + fib + 'g';
|
||||
document.getElementById('viewGoalWater').textContent = '≥' + wat + 'ml';
|
||||
closeGoalModal();
|
||||
document.getElementById('viewGoalFiber').textContent = '≥' + fib + 'g';
|
||||
document.getElementById('viewGoalWater').textContent = '≥' + wat + 'ml';
|
||||
closeModal('goalModal');
|
||||
alert('已保存(原型演示)');
|
||||
}
|
||||
|
||||
/* 点击遮罩层空白处关闭弹窗 */
|
||||
document.getElementById('diseaseModal').addEventListener('click', closeDiseaseModal);
|
||||
document.getElementById('goalModal').addEventListener('click', closeGoalModal);
|
||||
/* ========== 通用回写:将编辑态标签同步到页面展示区 ========== */
|
||||
// viewId: 展示区容器id; groupId: 编辑态分组id; cls: 展示态span的class; asText: true则拼成文本而非标签
|
||||
function syncGroupBack(viewId, groupId, cls, asText) {
|
||||
var view = document.getElementById(viewId);
|
||||
var state = editState[groupId];
|
||||
view.innerHTML = '';
|
||||
if (state.tags.length === 0) {
|
||||
view.innerHTML = '<span style="font-size:12px;color:#ccc;">暂无</span>';
|
||||
return;
|
||||
}
|
||||
if (asText) {
|
||||
view.textContent = state.tags.join('、');
|
||||
return;
|
||||
}
|
||||
state.tags.forEach(function(tag) {
|
||||
var s = document.createElement('span');
|
||||
s.className = cls;
|
||||
s.textContent = tag;
|
||||
view.appendChild(s);
|
||||
});
|
||||
}
|
||||
|
||||
/* ========== 点击遮罩层空白处关闭弹窗 ========== */
|
||||
['bodyModal','diseaseModal','tasteModal','tabooModal','dishModal','momModal','goalModal'].forEach(function(id) {
|
||||
var el = document.getElementById(id);
|
||||
if (el) el.addEventListener('click', function() { closeModal(id); });
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
</html>
|
||||
|
||||
@@ -88,6 +88,14 @@
|
||||
font-size: 15px; font-weight: 500; text-align: center; cursor: pointer;
|
||||
border: 1px solid #fde2e2; letter-spacing: 1px;
|
||||
}
|
||||
/* 模拟登录按钮(原型演示用) */
|
||||
.simulate-login-btn {
|
||||
display: block; width: calc(100% - 32px); margin: 20px auto 0; padding: 13px 0;
|
||||
border: none; border-radius: 22px; background: #07c160; color: #fff;
|
||||
font-size: 15px; font-weight: 600; text-align: center; cursor: pointer;
|
||||
letter-spacing: 1px; box-shadow: 0 6px 16px rgba(7, 193, 96, 0.24);
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -132,13 +140,15 @@
|
||||
<a class="menu-item" href="me-logs.html"><span class="m-icon">📝</span><span class="m-label">操作日志</span><span class="m-arrow">›</span></a>
|
||||
<a class="menu-item" href="me-settings.html"><span class="m-icon">⚙️</span><span class="m-label">设置</span><span class="m-arrow">›</span></a>
|
||||
</div>
|
||||
<!-- [交互] 原型演示入口:点击后跳转登录页查看登录效果 -->
|
||||
<a class="simulate-login-btn" href="me-login.html">模拟登录</a>
|
||||
<button class="logout-btn">退出登录</button>
|
||||
</div>
|
||||
<div class="tab-bar">
|
||||
<a class="tab-item" href="eat-home.html"><span class="tab-icon">🍽️</span>吃</a>
|
||||
<a class="tab-item" href="ask-home.html"><span class="tab-icon">💬</span>问</a>
|
||||
<a class="tab-item" href="make-home.html"><span class="tab-icon">🍳</span>做</a>
|
||||
<a class="tab-item active" href="me-login.html"><span class="tab-icon">👤</span>我</a>
|
||||
<a class="tab-item active" href="me-home.html"><span class="tab-icon">👤</span>我</a>
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
|
||||
@@ -61,6 +61,41 @@
|
||||
.advice-card { background: #fff; border-radius: 12px; padding: 12px 14px; margin: 0 16px 24px; }
|
||||
.advice-title { font-size: 12px; font-weight: 600; color: #333; margin-bottom: 8px; }
|
||||
.advice-text { font-size: 12px; color: #fa8c16; line-height: 1.7; }
|
||||
/* 净菜包订单详情专属样式 */
|
||||
.fulfill-section { padding: 12px 16px 0; }
|
||||
.sec-card { background: #fff; border-radius: 12px; padding: 14px; margin-bottom: 12px; box-shadow: 0 1px 4px rgba(0,0,0,0.06); }
|
||||
.sec-card .sec-title { font-size: 13px; font-weight: 600; color: #333; margin-bottom: 10px; }
|
||||
.info-row { display: flex; padding: 6px 0; font-size: 13px; border-bottom: 0.5px solid #f5f5f5; }
|
||||
.info-row:last-child { border-bottom: none; }
|
||||
.ir-label { width: 80px; color: #999; flex-shrink: 0; }
|
||||
.ir-value { flex: 1; color: #333; line-height: 1.5; }
|
||||
/* 时间线 */
|
||||
.timeline { padding: 4px 0 0; }
|
||||
.tl-item { display: flex; gap: 12px; padding: 0 0 20px; position: relative; }
|
||||
.tl-item:last-child { padding-bottom: 0; }
|
||||
.tl-item::before {
|
||||
content: ''; position: absolute; left: 5px; top: 14px; bottom: -4px;
|
||||
width: 2px; background: #e8e8e8;
|
||||
}
|
||||
.tl-item:last-child::before { display: none; }
|
||||
.tl-item.done::before { background: #52c41a; }
|
||||
.tl-dot {
|
||||
width: 12px; height: 12px; border-radius: 50%; background: #e8e8e8;
|
||||
flex-shrink: 0; margin-top: 4px; position: relative; z-index: 1;
|
||||
border: 2px solid #fff;
|
||||
}
|
||||
.tl-item.done .tl-dot { background: #52c41a; }
|
||||
.tl-item.active .tl-dot { background: #1677ff; box-shadow: 0 0 0 3px rgba(22,119,255,0.2); }
|
||||
.tl-content { flex: 1; }
|
||||
.tl-title { font-size: 13px; font-weight: 600; color: #999; }
|
||||
.tl-item.done .tl-title { color: #52c41a; }
|
||||
.tl-item.active .tl-title { color: #1677ff; }
|
||||
.tl-time { font-size: 11px; color: #999; margin-top: 2px; }
|
||||
.presale-tag {
|
||||
font-size: 10px; padding: 1px 6px; border-radius: 6px;
|
||||
background: #fff7e6; color: #fa8c16; font-weight: 600;
|
||||
}
|
||||
.hidden { display: none !important; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
@@ -75,7 +110,7 @@
|
||||
</div>
|
||||
<div class="page-content">
|
||||
<!-- 订单头部 -->
|
||||
<div class="order-header">
|
||||
<div class="order-header" id="orderHeader">
|
||||
<div class="oh-top">
|
||||
<div>
|
||||
<div class="oh-date">2026-04-28 午餐</div>
|
||||
@@ -95,8 +130,70 @@
|
||||
<span class="oh-tag" style="background:#f5f5f5;color:#666">余额支付</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 净菜包专属:履约信息 + 状态时间线(默认隐藏) -->
|
||||
<div class="fulfill-section hidden" id="cleanExtra">
|
||||
<div class="sec-card">
|
||||
<div class="sec-title">📦 履约信息</div>
|
||||
<div class="info-row">
|
||||
<span class="ir-label">取货方式</span>
|
||||
<span class="ir-value">🚚 配送到家</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="ir-label">期望配送</span>
|
||||
<span class="ir-value" style="color:#fa8c16;font-weight:600;">明日(4月29日)11:00-12:00</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="ir-label">收货地址</span>
|
||||
<span class="ir-value">张三 · 138****6688<br>渝北区龙湖路123号4栋1单元1801</span>
|
||||
</div>
|
||||
<div class="info-row">
|
||||
<span class="ir-label">配送费用</span>
|
||||
<span class="ir-value">¥0(满79免运费)</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="sec-card">
|
||||
<div class="sec-title">⏱ 订单进度</div>
|
||||
<div class="timeline">
|
||||
<div class="tl-item done">
|
||||
<div class="tl-dot"></div>
|
||||
<div class="tl-content">
|
||||
<div class="tl-title">订单提交</div>
|
||||
<div class="tl-time">2026-04-28 14:23</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl-item done">
|
||||
<div class="tl-dot"></div>
|
||||
<div class="tl-content">
|
||||
<div class="tl-title">备货完成</div>
|
||||
<div class="tl-time">2026-04-28 15:00 截单</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl-item active">
|
||||
<div class="tl-dot"></div>
|
||||
<div class="tl-content">
|
||||
<div class="tl-title">待配送</div>
|
||||
<div class="tl-time">预计 2026-04-29 11:00 开始配送</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl-item">
|
||||
<div class="tl-dot"></div>
|
||||
<div class="tl-content">
|
||||
<div class="tl-title">配送中</div>
|
||||
<div class="tl-time">-</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl-item">
|
||||
<div class="tl-dot"></div>
|
||||
<div class="tl-content">
|
||||
<div class="tl-title">已送达</div>
|
||||
<div class="tl-time">-</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- 菜品明细 -->
|
||||
<div class="dish-section">
|
||||
<div class="dish-section" id="dishSection">
|
||||
<div class="dish-sec-title">菜品明细 · 食材 · 溯源</div>
|
||||
<!-- 清蒸鱼 -->
|
||||
<div class="dish-card">
|
||||
@@ -188,5 +285,84 @@
|
||||
</div>
|
||||
<div class="home-indicator"></div>
|
||||
</div>
|
||||
<script>
|
||||
/* 解析 URL type 参数,净菜包订单渲染对应详情 */
|
||||
function getQuery(name) {
|
||||
var m = new RegExp('[?&]' + name + '=([^&]*)').exec(location.search);
|
||||
return m ? decodeURIComponent(m[1]) : '';
|
||||
}
|
||||
|
||||
var type = getQuery('type') === 'clean' ? 'clean' : 'meal';
|
||||
if (type === 'clean') {
|
||||
/* 替换订单头部:净菜包订单基本信息 */
|
||||
document.getElementById('orderHeader').innerHTML =
|
||||
'<div class="oh-top">'
|
||||
+ '<div>'
|
||||
+ '<div class="oh-date">2026-04-29 午餐时段配送</div>'
|
||||
+ '<div class="oh-id">CL-20260428-017</div>'
|
||||
+ '</div>'
|
||||
+ '<span class="oh-badge" style="background:#e6f4ff;color:#1677ff;">🚚 待配送</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="oh-stats">'
|
||||
+ '<div class="oh-stat"><div class="sv" style="color:#fa8c16">890</div><div class="sl">总热量kcal</div></div>'
|
||||
+ '<div class="oh-stat"><div class="sv" style="color:#f5222d">¥79</div><div class="sl">消费金额</div></div>'
|
||||
+ '<div class="oh-stat"><div class="sv" style="color:#1677ff">2</div><div class="sl">净菜包种类</div></div>'
|
||||
+ '<div class="oh-stat"><div class="sv" style="color:#722ed1">1.0kg</div><div class="sl">总净重</div></div>'
|
||||
+ '</div>'
|
||||
+ '<div class="oh-tags">'
|
||||
+ '<span class="oh-tag" style="background:#fff7e6;color:#fa8c16">预售订单</span>'
|
||||
+ '<span class="oh-tag" style="background:#e6f4ff;color:#1677ff">配送到家</span>'
|
||||
+ '<span class="oh-tag" style="background:#f5f5f5;color:#666">余额支付</span>'
|
||||
+ '</div>';
|
||||
|
||||
/* 显示履约信息 + 订单进度时间线 */
|
||||
document.getElementById('cleanExtra').classList.remove('hidden');
|
||||
|
||||
/* 替换菜品明细:餐品 → 净菜包明细 */
|
||||
document.getElementById('dishSection').innerHTML =
|
||||
'<div class="dish-sec-title">净菜包明细 · 食材 · 溯源</div>'
|
||||
+ '<div class="dish-card">'
|
||||
+ '<div class="dish-head">'
|
||||
+ '<div class="dish-icon">🍗</div>'
|
||||
+ '<div class="dish-info">'
|
||||
+ '<div class="dish-name-row">'
|
||||
+ '<span class="dish-name">宫保鸡丁净菜包</span>'
|
||||
+ '<span class="presale-tag">预售 ×2</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="dish-meta">约300g/份 · 腌好鸡丁+配料包 · 共600g · 285kcal/份</div>'
|
||||
+ '</div>'
|
||||
+ '<span class="dish-price">¥44</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="ing-section">'
|
||||
+ '<div class="ing-label">食材来源</div>'
|
||||
+ '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">鸡胸肉</div><div class="ing-code">NC-PROC-JBR-20260422-01</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>'
|
||||
+ '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">花生米</div><div class="ing-code">ST-EX-HS05-PT-HSMI-050K-20260420-001</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
+ '<div class="dish-card">'
|
||||
+ '<div class="dish-head">'
|
||||
+ '<div class="dish-icon">🥗</div>'
|
||||
+ '<div class="dish-info">'
|
||||
+ '<div class="dish-name-row">'
|
||||
+ '<span class="dish-name">低脂控糖套餐净菜包</span>'
|
||||
+ '<span class="presale-tag">预售 ×1</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="dish-meta">约400g · 鸡胸+糙米饭+西兰花 · 320kcal</div>'
|
||||
+ '</div>'
|
||||
+ '<span class="dish-price">¥35</span>'
|
||||
+ '</div>'
|
||||
+ '<div class="ing-section">'
|
||||
+ '<div class="ing-label">食材来源</div>'
|
||||
+ '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">鸡胸肉</div><div class="ing-code">NC-PROC-JBR-20260422-01</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>'
|
||||
+ '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">西兰花</div><div class="ing-code">ST-EX-LY01-VG-XLHU-080K-20260416-001</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>'
|
||||
+ '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">糙米</div><div class="ing-code">ST-EX-LY03-DG-CAMI-500K-20260413-002</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>'
|
||||
+ '</div>'
|
||||
+ '</div>'
|
||||
+ '<div class="advice-card" style="margin:0;">'
|
||||
+ '<div class="advice-title">🍳 烹制提示</div>'
|
||||
+ '<div class="advice-text" style="color:#1677ff;">宫保鸡丁净菜包:热锅冷油下鸡丁滑炒至变色,加入配料包翻炒 2 分钟即可出锅;糙米饭需另行准备。</div>'
|
||||
+ '</div>';
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -24,11 +24,22 @@
|
||||
.order-tabs .ot.active { color: #1677ff; font-weight: 600; }
|
||||
.order-tabs .ot.active::after { content: ''; position: absolute; bottom: 0; left: 30%; right: 30%; height: 2px; background: #1677ff; border-radius: 1px; }
|
||||
.order-card { margin: 0 12px 10px; background: #fff; border-radius: 10px; padding: 14px; text-decoration: none; color: inherit; display: block; }
|
||||
.order-card .card-top { display: flex; justify-content: space-between; margin-bottom: 10px; }
|
||||
.order-card .card-top { display: flex; justify-content: space-between; align-items: flex-start; margin-bottom: 10px; }
|
||||
.order-card .shop-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
|
||||
.order-card .shop { font-size: 14px; font-weight: 600; }
|
||||
.order-card .type-tag { font-size: 10px; padding: 1px 6px; border-radius: 8px; font-weight: 600; line-height: 16px; }
|
||||
.order-card .type-tag.meal { background: #e6f4ff; color: #1677ff; }
|
||||
.order-card .type-tag.clean { background: #fff7e6; color: #fa8c16; }
|
||||
.order-card .status { font-size: 12px; color: #52c41a; font-weight: 500; }
|
||||
.order-card .status.pending { color: #fa8c16; }
|
||||
.order-card .status.shipping { color: #1677ff; }
|
||||
.order-card .status.processing { color: #722ed1; }
|
||||
.order-card .items { font-size: 12px; color: #666; margin-bottom: 8px; line-height: 1.6; }
|
||||
.order-card .fulfill-meta {
|
||||
font-size: 11px; color: #fa8c16; margin-bottom: 8px; padding: 4px 8px;
|
||||
background: #fff7e6; border-radius: 6px; display: flex; align-items: center; gap: 4px;
|
||||
}
|
||||
.order-card .fulfill-meta.done { color: #52c41a; background: #f6ffed; }
|
||||
.order-card .card-bottom { display: flex; justify-content: space-between; align-items: center; }
|
||||
.order-card .total { font-size: 14px; font-weight: 700; color: #f5222d; }
|
||||
.order-card .time { font-size: 11px; color: #999; }
|
||||
@@ -48,20 +59,48 @@
|
||||
<div class="order-tabs">
|
||||
<span class="ot active">全部</span>
|
||||
<span class="ot">待取餐</span>
|
||||
<span class="ot">待配送</span>
|
||||
<span class="ot">已完成</span>
|
||||
</div>
|
||||
<a class="order-card" href="me-order-detail-pending.html">
|
||||
<div class="card-top"><span class="shop">🍽️ 阳光食堂 · 午餐</span><span class="status pending">待取餐</span></div>
|
||||
<div class="card-top">
|
||||
<div class="shop-row"><span class="shop">🍽️ 阳光食堂 · 午餐</span><span class="type-tag meal">餐品</span></div>
|
||||
<span class="status pending">待取餐</span>
|
||||
</div>
|
||||
<div class="items">低脂鸡胸肉沙拉 ×1、杂粮饭 ×1、紫菜蛋花汤 ×1</div>
|
||||
<div class="card-bottom"><span class="total">¥ 28.5</span><span class="time">今天 11:32</span></div>
|
||||
</a>
|
||||
<a class="order-card" href="me-order-detail.html?type=clean">
|
||||
<div class="card-top">
|
||||
<div class="shop-row"><span class="shop">🥬 阳光食堂 · 净菜包订单</span><span class="type-tag clean">净菜包</span></div>
|
||||
<span class="status shipping">待配送</span>
|
||||
</div>
|
||||
<div class="items">宫保鸡丁净菜包 ×2、低脂控糖套餐净菜包 ×1</div>
|
||||
<div class="fulfill-meta">🚚 配送到家 · 明日(4月29日)11:00-12:00</div>
|
||||
<div class="card-bottom"><span class="total">¥ 79.0</span><span class="time">今天 14:23 下单</span></div>
|
||||
</a>
|
||||
<a class="order-card" href="me-order-detail.html">
|
||||
<div class="card-top"><span class="shop">🍽️ 阳光食堂 · 早餐</span><span class="status">已完成</span></div>
|
||||
<div class="card-top">
|
||||
<div class="shop-row"><span class="shop">🍽️ 阳光食堂 · 早餐</span><span class="type-tag meal">餐品</span></div>
|
||||
<span class="status">已完成</span>
|
||||
</div>
|
||||
<div class="items">全麦三明治 ×1、鲜榨橙汁 ×1</div>
|
||||
<div class="card-bottom"><span class="total">¥ 15.0</span><span class="time">今天 07:45</span></div>
|
||||
</a>
|
||||
<a class="order-card" href="me-order-detail.html?type=clean">
|
||||
<div class="card-top">
|
||||
<div class="shop-row"><span class="shop">🥬 阳光食堂 · 净菜包订单</span><span class="type-tag clean">净菜包</span></div>
|
||||
<span class="status">已完成</span>
|
||||
</div>
|
||||
<div class="items">红烧肉净菜包 ×1、番茄炒蛋净菜包 ×1</div>
|
||||
<div class="fulfill-meta done">🏪 食堂自提 · 已取货</div>
|
||||
<div class="card-bottom"><span class="total">¥ 36.0</span><span class="time">昨天 12:15</span></div>
|
||||
</a>
|
||||
<a class="order-card" href="me-order-detail.html">
|
||||
<div class="card-top"><span class="shop">🍽️ 健康轻食 · 午餐</span><span class="status">已完成</span></div>
|
||||
<div class="card-top">
|
||||
<div class="shop-row"><span class="shop">🍽️ 健康轻食 · 午餐</span><span class="type-tag meal">餐品</span></div>
|
||||
<span class="status">已完成</span>
|
||||
</div>
|
||||
<div class="items">三文鱼牛油果碗 ×1、蔬菜汁 ×1</div>
|
||||
<div class="card-bottom"><span class="total">¥ 42.0</span><span class="time">昨天 12:15</span></div>
|
||||
</a>
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
@echo off
|
||||
echo ============================================
|
||||
echo 健康CQ原型 - 本地预览服务器
|
||||
echo ============================================
|
||||
echo.
|
||||
echo 打开浏览器访问: http://localhost:3000/
|
||||
echo 按 Ctrl+C 停止服务器
|
||||
echo.
|
||||
node server.js
|
||||
pause
|
||||
@@ -88,6 +88,14 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
|
||||
.spec-toggle.active .spec-toggle__switch::after{transform:translateX(14px);}
|
||||
.spec-toggle__label{font-size:11px;color:var(--text-placeholder);}
|
||||
.spec-toggle.active .spec-toggle__label{color:var(--primary);font-weight:500;}
|
||||
/* 外售净菜包胶囊开关 */
|
||||
.sale-toggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer;user-select:none;}
|
||||
.sale-toggle__switch{width:32px;height:18px;background:#D9D9D9;border-radius:9px;position:relative;transition:background .2s;flex-shrink:0;}
|
||||
.sale-toggle__switch::after{content:'';position:absolute;left:2px;top:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .2s;box-shadow:0 1px 2px rgba(0,0,0,0.15);}
|
||||
.sale-toggle.active .sale-toggle__switch{background:var(--success);}
|
||||
.sale-toggle.active .sale-toggle__switch::after{transform:translateX(14px);}
|
||||
.sale-toggle__label{font-size:11px;color:var(--text-placeholder);}
|
||||
.sale-toggle.active .sale-toggle__label{color:var(--success);font-weight:500;}
|
||||
.btn-text{background:none;border:none;cursor:pointer;font-size:12px;padding:2px 6px;border-radius:var(--radius-sm);transition:all .15s;}
|
||||
.btn-text--primary{color:var(--primary);}.btn-text--primary:hover{background:var(--primary-light);}
|
||||
.btn-text--danger{color:var(--danger);}.btn-text--danger:hover{background:#FFF1F0;}
|
||||
@@ -361,11 +369,11 @@ var STEP_HTML = [
|
||||
<button type="button" class="dynamic-row-add" onclick="addCrowdRow()">+ 添加人群</button>
|
||||
<div class="form-subtitle">📐 餐品规格</div>
|
||||
<table class="spec-table" id="specTable">
|
||||
<thead><tr><th>规格</th><th>单位重量(g)</th><th>售价(元/份)</th><th>默认</th><th style="width:60px;">操作</th></tr></thead>
|
||||
<thead><tr><th>规格</th><th>单位重量(g)</th><th>餐品售价(元/份)</th><th>净菜包售价(元/份)</th><th>外售净菜包</th><th>默认</th><th style="width:60px;">操作</th></tr></thead>
|
||||
<tbody id="specBody">
|
||||
<tr><td>标准份</td><td>350</td><td>15.00</td><td><div class="spec-toggle active" onclick="toggleDefault(this)"><span class="spec-toggle__switch"></span><span class="spec-toggle__label">默认</span></div></td><td><button class="btn-text btn-text--danger" onclick="removeSpec(this)">删除</button></td></tr>
|
||||
<tr><td>小份</td><td>200</td><td>10.00</td><td><div class="spec-toggle" onclick="toggleDefault(this)"><span class="spec-toggle__switch"></span><span class="spec-toggle__label">默认</span></div></td><td><button class="btn-text btn-text--danger" onclick="removeSpec(this)">删除</button></td></tr>
|
||||
<tr class="spec-add-row" onclick="addSpecRow(this)"><td colspan="5" style="text-align:center;">+ 添加规格</td></tr>
|
||||
<tr><td>标准份</td><td>350</td><td>15.00</td><td>10.00</td><td><div class="sale-toggle" onclick="toggleCleanSale(this)"><span class="sale-toggle__switch"></span><span class="sale-toggle__label">下架</span></div></td><td><div class="spec-toggle active" onclick="toggleDefault(this)"><span class="spec-toggle__switch"></span><span class="spec-toggle__label">默认</span></div></td><td><button class="btn-text btn-text--danger" onclick="removeSpec(this)">删除</button></td></tr>
|
||||
<tr><td>小份</td><td>200</td><td>10.00</td><td>7.00</td><td><div class="sale-toggle" onclick="toggleCleanSale(this)"><span class="sale-toggle__switch"></span><span class="sale-toggle__label">下架</span></div></td><td><div class="spec-toggle" onclick="toggleDefault(this)"><span class="spec-toggle__switch"></span><span class="spec-toggle__label">默认</span></div></td><td><button class="btn-text btn-text--danger" onclick="removeSpec(this)">删除</button></td></tr>
|
||||
<tr class="spec-add-row" onclick="addSpecRow(this)"><td colspan="7" style="text-align:center;">+ 添加规格</td></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="form-subtitle">📷 菜品展示</div>
|
||||
@@ -517,7 +525,7 @@ function addSpecRow(addRow){
|
||||
if(document.querySelector('.spec-edit-row')) return;
|
||||
var tr=document.createElement('tr');
|
||||
tr.className='spec-edit-row';
|
||||
tr.innerHTML='<td><select class="form-select" style="height:28px;font-size:12px;padding:0 24px 0 8px;"><option>请选择</option><option>标准份</option><option>小份</option><option>大份</option><option>迷你份</option><option>加大份</option></select></td><td><input class="form-input" type="number" placeholder="重量"></td><td><input class="form-input" type="number" placeholder="售价"></td><td></td><td><button class="btn-text btn-text--primary" onclick="confirmSpec(this)">确定</button> <button class="btn-text btn-text--danger" onclick="cancelSpec(this)">取消</button></td>';
|
||||
tr.innerHTML='<td><select class="form-select" style="height:28px;font-size:12px;padding:0 24px 0 8px;"><option>请选择</option><option>标准份</option><option>小份</option><option>大份</option><option>迷你份</option><option>加大份</option></select></td><td><input class="form-input" type="number" placeholder="重量"></td><td><input class="form-input" type="number" placeholder="餐品售价"></td><td><input class="form-input" type="number" placeholder="净菜包售价"></td><td><div class="sale-toggle" onclick="toggleCleanSale(this)"><span class="sale-toggle__switch"></span><span class="sale-toggle__label">下架</span></div></td><td></td><td><button class="btn-text btn-text--primary" onclick="confirmSpec(this)">确定</button> <button class="btn-text btn-text--danger" onclick="cancelSpec(this)">取消</button></td>';
|
||||
addRow.parentNode.insertBefore(tr,addRow);
|
||||
}
|
||||
function confirmSpec(btn){
|
||||
@@ -525,10 +533,18 @@ function confirmSpec(btn){
|
||||
var sel=row.querySelector('select');
|
||||
var inputs=row.querySelectorAll('input');
|
||||
var name=sel?sel.value:'';
|
||||
var weight=inputs[0].value.trim(),price=inputs[1].value.trim();
|
||||
var weight=inputs[0].value.trim(),price=inputs[1].value.trim(),cleanPrice=inputs[2].value.trim();
|
||||
if(!name||name==='请选择'||!weight||!price){alert('请填写完整信息');return;}
|
||||
var cleanPriceText = cleanPrice ? parseFloat(cleanPrice).toFixed(2) : '—';
|
||||
var saleActive = !!row.querySelector('.sale-toggle.active');
|
||||
var saleHtml = '<div class="sale-toggle'+(saleActive?' active':'')+'" onclick="toggleCleanSale(this)"><span class="sale-toggle__switch"></span><span class="sale-toggle__label">'+(saleActive?'上架':'下架')+'</span></div>';
|
||||
row.className='';
|
||||
row.innerHTML='<td>'+name+'</td><td>'+weight+'</td><td>'+parseFloat(price).toFixed(2)+'</td><td><div class="spec-toggle" onclick="toggleDefault(this)"><span class="spec-toggle__switch"></span><span class="spec-toggle__label">默认</span></div></td><td><button class="btn-text btn-text--danger" onclick="removeSpec(this)">删除</button></td>';
|
||||
row.innerHTML='<td>'+name+'</td><td>'+weight+'</td><td>'+parseFloat(price).toFixed(2)+'</td><td>'+cleanPriceText+'</td><td>'+saleHtml+'</td><td><div class="spec-toggle" onclick="toggleDefault(this)"><span class="spec-toggle__switch"></span><span class="spec-toggle__label">默认</span></div></td><td><button class="btn-text btn-text--danger" onclick="removeSpec(this)">删除</button></td>';
|
||||
}
|
||||
function toggleCleanSale(el){
|
||||
var active = el.classList.toggle('active');
|
||||
var label = el.querySelector('.sale-toggle__label');
|
||||
if(label) label.textContent = active ? '上架' : '下架';
|
||||
}
|
||||
function cancelSpec(btn){btn.closest('tr').remove();}
|
||||
function toggleDefault(el){
|
||||
@@ -678,7 +694,7 @@ var EDIT_DATA = {
|
||||
name:'红烧肉', category:'荤菜', method:'炖', meal:'午/晚', pyramid:'畜禽肉蛋水产',
|
||||
allergen:'无', tag:'高蛋白', status:'上架',
|
||||
crowd:[{name:'成人',level:'推荐'},{name:'高血脂人群',level:'慎食'},{name:'高血压人群',level:'适量'}],
|
||||
specs:[{spec:'标准份',weight:200,price:12,isDefault:true},{spec:'小份',weight:120,price:8,isDefault:false},{spec:'大份',weight:300,price:18,isDefault:false}],
|
||||
specs:[{spec:'标准份',weight:200,price:12,cleanPrice:9,cleanSale:false,isDefault:true},{spec:'小份',weight:120,price:8,cleanPrice:6,cleanSale:false,isDefault:false},{spec:'大份',weight:300,price:18,cleanPrice:13,cleanSale:false,isDefault:false}],
|
||||
composition:[{name:'五花肉',netType:'红烧块',amount:150,pct:'60%',type:'主材',allergen:'无',note:'—'},{name:'冰糖',netType:'糖浆',amount:20,pct:'8%',type:'调料',allergen:'无',note:'上色'},{name:'酱油',netType:'调味汁',amount:15,pct:'6%',type:'调料',allergen:'含大豆',note:'调味'},{name:'料酒',netType:'料酒汁',amount:10,pct:'4%',type:'调料',allergen:'无',note:'去腥'}],
|
||||
cook:{mainMethod:'炖',subMethod:'煎',heat:'中火→小火',duration:45,oil:15,salt:3,temp:100,output:200,steps:6,desc:'1.五花肉切块焯水;2.锅中煎至金黄;3.加冰糖炒色;4.加酱油料酒;5.加水小火炖40分钟;6.大火收汁'},
|
||||
nutri:{calorie:385,protein:18.2,carb:12.4,fat:28.6,vitC:2.1,mineral:45,fiber:1.8,sodium:486},
|
||||
@@ -720,7 +736,7 @@ if(pageMode==='convert' && INNOV){
|
||||
EDIT_DATA.tag = INNOV.tag;
|
||||
EDIT_DATA.status = '上架';
|
||||
EDIT_DATA.crowd = [];
|
||||
EDIT_DATA.specs = [{spec:'标准份',weight:350,price:15,isDefault:true},{spec:'小份',weight:200,price:10,isDefault:false}];
|
||||
EDIT_DATA.specs = [{spec:'标准份',weight:350,price:15,cleanPrice:10,cleanSale:false,isDefault:true},{spec:'小份',weight:200,price:10,cleanPrice:7,cleanSale:false,isDefault:false}];
|
||||
EDIT_DATA.composition = INNOV.composition;
|
||||
EDIT_DATA.cook = INNOV.cook;
|
||||
EDIT_DATA.nutri = INNOV.nutri;
|
||||
@@ -762,7 +778,9 @@ function fillEditData(){
|
||||
specBody.innerHTML = '';
|
||||
d.specs.forEach(function(s){
|
||||
var tr = document.createElement('tr');
|
||||
tr.innerHTML = '<td><select class="form-select form-select--sm"><option'+(s.spec==='标准份'?' selected':'')+'>标准份</option><option'+(s.spec==='小份'?' selected':'')+'>小份</option><option'+(s.spec==='大份'?' selected':'')+'>大份</option><option'+(s.spec==='加大份'?' selected':'')+'>加大份</option></select></td><td><input class="form-input form-input--sm" value="'+s.weight+'"></td><td><input class="form-input form-input--sm" value="'+s.price+'"></td><td><input type="checkbox"'+(s.isDefault?' checked':'')+'></td><td><span class="link" onclick="this.closest(\'tr\').remove()">删除</span></td>';
|
||||
var saleActive = s.cleanSale === true;
|
||||
var saleHtml = '<div class="sale-toggle'+(saleActive?' active':'')+'" onclick="toggleCleanSale(this)"><span class="sale-toggle__switch"></span><span class="sale-toggle__label">'+(saleActive?'上架':'下架')+'</span></div>';
|
||||
tr.innerHTML = '<td><select class="form-select form-select--sm"><option'+(s.spec==='标准份'?' selected':'')+'>标准份</option><option'+(s.spec==='小份'?' selected':'')+'>小份</option><option'+(s.spec==='大份'?' selected':'')+'>大份</option><option'+(s.spec==='加大份'?' selected':'')+'>加大份</option></select></td><td><input class="form-input form-input--sm" value="'+s.weight+'"></td><td><input class="form-input form-input--sm" value="'+s.price+'"></td><td><input class="form-input form-input--sm" value="'+(s.cleanPrice!==undefined?s.cleanPrice:'')+'"></td><td>'+saleHtml+'</td><td><input type="checkbox"'+(s.isDefault?' checked':'')+'></td><td><span class="link" onclick="this.closest(\'tr\').remove()">删除</span></td>';
|
||||
specBody.appendChild(tr);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,6 +115,14 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
|
||||
.info-table tr:hover{background:#F8FBFF;}
|
||||
.spec-detail-table th{padding:6px 12px;font-size:12px;}
|
||||
.spec-detail-table td{padding:6px 12px;font-size:12px;}
|
||||
/* 外售净菜包胶囊开关 */
|
||||
.sale-toggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer;user-select:none;}
|
||||
.sale-toggle__switch{width:32px;height:18px;background:#D9D9D9;border-radius:9px;position:relative;transition:background .2s;flex-shrink:0;}
|
||||
.sale-toggle__switch::after{content:'';position:absolute;left:2px;top:2px;width:14px;height:14px;background:#fff;border-radius:50%;transition:transform .2s;box-shadow:0 1px 2px rgba(0,0,0,0.15);}
|
||||
.sale-toggle.active .sale-toggle__switch{background:var(--success);}
|
||||
.sale-toggle.active .sale-toggle__switch::after{transform:translateX(14px);}
|
||||
.sale-toggle__label{font-size:11px;color:var(--text-placeholder);}
|
||||
.sale-toggle.active .sale-toggle__label{color:var(--success);font-weight:500;}
|
||||
|
||||
/* 图片/视频网格 */
|
||||
.media-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
|
||||
@@ -274,7 +282,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
|
||||
<script>
|
||||
// 餐品数据
|
||||
const DISHES = [
|
||||
{id:'DISH001',name:'红烧肉',icon:'🥩',category:'荤菜',tags:['高蛋白'],specs:[{name:'标准份',weight:200,price:12,isDefault:true},{name:'小份',weight:120,price:8},{name:'大份',weight:300,price:18}],method:'炖',meal:'午/晚',allergen:'无',status:'启用',source:'手动添加',weightBasePrice:'6.00',weightVipPrice:'5.40',crowd:[{name:'成人',level:'推荐'},{name:'高血脂人群',level:'慎食'},{name:'高血压人群',level:'适量'}],crowdNote:'高血脂人群控制摄入量',
|
||||
{id:'DISH001',name:'红烧肉',icon:'🥩',category:'荤菜',tags:['高蛋白'],specs:[{name:'标准份',weight:200,price:12,cleanPrice:9,cleanSale:false,isDefault:true},{name:'小份',weight:120,price:8,cleanPrice:6,cleanSale:false},{name:'大份',weight:300,price:18,cleanPrice:13,cleanSale:false}],method:'炖',meal:'午/晚',allergen:'无',status:'启用',source:'手动添加',weightBasePrice:'6.00',weightVipPrice:'5.40',crowd:[{name:'成人',level:'推荐'},{name:'高血脂人群',level:'慎食'},{name:'高血压人群',level:'适量'}],crowdNote:'高血脂人群控制摄入量',
|
||||
composition:[{name:'猪五花肉',netType:'红烧块',amount:160,pct:'80%',state:'净菜',type:'主材',allergen:'无',note:'—'},{name:'生姜',netType:'姜片',amount:5,pct:'2.5%',state:'净菜',type:'辅材',allergen:'无',note:'—'},{name:'生抽',netType:'调味汁',amount:15,pct:'7.5%',state:'原料',type:'调料',allergen:'含麸质',note:'酱油'},{name:'冰糖',netType:'糖浆',amount:10,pct:'5%',state:'原料',type:'调料',allergen:'无',note:'上色提味'},{name:'料酒',netType:'料酒汁',amount:10,pct:'5%',state:'原料',type:'调料',allergen:'无',note:'去腥'}],
|
||||
nutri:{calorie:385,protein:18.2,carb:12.4,fat:28.6,vitC:0.8,mineral:42,fiber:0.3,sodium:486,nutriGrade:'偏差',note:'铁2.4mg、锌1.8mg'},
|
||||
cook:{mainMethod:'炖',subMethod:'煎',heat:'中火→小火',duration:45,oil:15,salt:3,temp:'100→80',output:200,steps:6},
|
||||
@@ -282,7 +290,7 @@ const DISHES = [
|
||||
color:{mainColor:'红褐色',uniformity:4,gloss:4,freshness:4,appearance:4,colorScore:4.0,colorGrade:'良好'},
|
||||
texture:{hardness:2,sticky:3,crispy:1,smooth:4,elastic:3,textureScore:3.6,textureGrade:'良好'}
|
||||
},
|
||||
{id:'DISH002',name:'清炒时蔬',icon:'🥬',category:'素菜',tags:['低脂','素食'],specs:[{name:'标准份',weight:150,price:6,isDefault:true},{name:'小份',weight:100,price:4}],method:'炒',meal:'早/午/晚',allergen:'无',status:'启用',source:'系统内置',weightBasePrice:'3.00',weightVipPrice:'2.70',crowd:[{name:'全人群',level:'推荐'},{name:'糖尿病人群',level:'推荐'},{name:'肾结石人群',level:'慎食'}],crowdNote:'肾结石人群慎食(草酸含量高)',
|
||||
{id:'DISH002',name:'清炒时蔬',icon:'🥬',category:'素菜',tags:['低脂','素食'],specs:[{name:'标准份',weight:150,price:6,cleanPrice:4.5,cleanSale:false,isDefault:true},{name:'小份',weight:100,price:4,cleanPrice:3,cleanSale:false}],method:'炒',meal:'早/午/晚',allergen:'无',status:'启用',source:'系统内置',weightBasePrice:'3.00',weightVipPrice:'2.70',crowd:[{name:'全人群',level:'推荐'},{name:'糖尿病人群',level:'推荐'},{name:'肾结石人群',level:'慎食'}],crowdNote:'肾结石人群慎食(草酸含量高)',
|
||||
composition:[{name:'时令青菜',netType:'青菜段',amount:120,pct:'80%',state:'净菜',type:'主材',allergen:'无',note:'—'},{name:'蒜末',netType:'蒜末',amount:5,pct:'3.3%',state:'净菜',type:'调料',allergen:'无',note:'—'},{name:'食用油',netType:'净油',amount:8,pct:'5.3%',state:'原料',type:'调料',allergen:'无',note:'—'},{name:'食盐',netType:'盐粒',amount:2,pct:'1.3%',state:'原料',type:'调料',allergen:'无',note:'—'}],
|
||||
nutri:{calorie:68,protein:2.1,carb:8.6,fat:3.2,vitC:28.5,mineral:86,fiber:2.4,sodium:186,nutriGrade:'达标',note:'铁1.2mg、钙45mg'},
|
||||
cook:{mainMethod:'炒',subMethod:'—',heat:'大火',duration:5,oil:8,salt:2,temp:'200',output:150,steps:4},
|
||||
@@ -290,7 +298,7 @@ const DISHES = [
|
||||
color:{mainColor:'翠绿色',uniformity:5,gloss:4,freshness:5,appearance:4,colorScore:4.5,colorGrade:'优秀'},
|
||||
texture:{hardness:3,sticky:1,crispy:4,smooth:3,elastic:2,textureScore:3.4,textureGrade:'良好'}
|
||||
},
|
||||
{id:'DISH003',name:'番茄鸡蛋汤',icon:'🍅',category:'汤品',tags:['低卡'],specs:[{name:'标准份',weight:300,price:5,isDefault:true}],method:'煮',meal:'午/晚',allergen:'含蛋类',status:'启用',source:'系统内置',weightBasePrice:'1.67',weightVipPrice:'1.50',crowd:[{name:'全人群',level:'推荐'},{name:'儿童',level:'推荐'},{name:'老年人',level:'推荐'}],crowdNote:'',
|
||||
{id:'DISH003',name:'番茄鸡蛋汤',icon:'🍅',category:'汤品',tags:['低卡'],specs:[{name:'标准份',weight:300,price:5,cleanPrice:3.5,cleanSale:false,isDefault:true}],method:'煮',meal:'午/晚',allergen:'含蛋类',status:'启用',source:'系统内置',weightBasePrice:'1.67',weightVipPrice:'1.50',crowd:[{name:'全人群',level:'推荐'},{name:'儿童',level:'推荐'},{name:'老年人',level:'推荐'}],crowdNote:'',
|
||||
composition:[{name:'番茄',netType:'番茄块',amount:150,pct:'50%',state:'净菜',type:'主材',allergen:'无',note:'—'},{name:'鸡蛋',netType:'鸡蛋液',amount:60,pct:'20%',state:'原料',type:'主材',allergen:'含蛋类',note:'—'},{name:'食用油',netType:'净油',amount:5,pct:'1.7%',state:'原料',type:'调料',allergen:'无',note:'—'},{name:'食盐',netType:'盐粒',amount:2,pct:'0.7%',state:'原料',type:'调料',allergen:'无',note:'—'}],
|
||||
nutri:{calorie:45,protein:3.8,carb:4.2,fat:2.1,vitC:18.2,mineral:32,fiber:1.1,sodium:280,nutriGrade:'达标',note:'铁0.8mg、钾210mg'},
|
||||
cook:{mainMethod:'煮',subMethod:'炒',heat:'中火',duration:12,oil:5,salt:2,temp:'100',output:300,steps:5},
|
||||
@@ -298,7 +306,7 @@ const DISHES = [
|
||||
color:{mainColor:'橙红色',uniformity:4,gloss:3,freshness:5,appearance:4,colorScore:4.0,colorGrade:'良好'},
|
||||
texture:{hardness:1,sticky:2,crispy:1,smooth:5,elastic:2,textureScore:3.8,textureGrade:'良好'}
|
||||
},
|
||||
{id:'DISH004',name:'米饭',icon:'🍚',category:'主食',tags:['主食'],specs:[{name:'标准份',weight:200,price:3,isDefault:true},{name:'小份',weight:100,price:2},{name:'大份',weight:300,price:4}],method:'蒸',meal:'早/午/晚',allergen:'无',status:'启用',source:'系统内置',weightBasePrice:'1.50',weightVipPrice:'1.35',crowd:[{name:'全人群',level:'推荐'},{name:'糖尿病人群',level:'适量'}],crowdNote:'糖尿病人群注意控制量',
|
||||
{id:'DISH004',name:'米饭',icon:'🍚',category:'主食',tags:['主食'],specs:[{name:'标准份',weight:200,price:3,cleanPrice:2,cleanSale:false,isDefault:true},{name:'小份',weight:100,price:2,cleanPrice:1.5,cleanSale:false},{name:'大份',weight:300,price:4,cleanPrice:3,cleanSale:false}],method:'蒸',meal:'早/午/晚',allergen:'无',status:'启用',source:'系统内置',weightBasePrice:'1.50',weightVipPrice:'1.35',crowd:[{name:'全人群',level:'推荐'},{name:'糖尿病人群',level:'适量'}],crowdNote:'糖尿病人群注意控制量',
|
||||
composition:[{name:'大米',netType:'熟米饭',amount:100,pct:'100%',state:'原料',type:'主材',allergen:'无',note:'—'}],
|
||||
nutri:{calorie:232,protein:4.8,carb:51.2,fat:0.6,vitC:0,mineral:12,fiber:0.4,sodium:3,nutriGrade:'达标',note:'—'},
|
||||
cook:{mainMethod:'蒸',subMethod:'—',heat:'大火→中火',duration:30,oil:0,salt:0,temp:'100',output:200,steps:2},
|
||||
@@ -306,7 +314,7 @@ const DISHES = [
|
||||
color:{mainColor:'乳白色',uniformity:5,gloss:4,freshness:4,appearance:4,colorScore:4.2,colorGrade:'良好'},
|
||||
texture:{hardness:2,sticky:3,crispy:1,smooth:3,elastic:2,textureScore:3.2,textureGrade:'一般'}
|
||||
},
|
||||
{id:'DISH005',name:'糖醋里脊',icon:'🍖',category:'荤菜',tags:['高糖'],specs:[{name:'标准份',weight:180,price:14,isDefault:true},{name:'大份',weight:280,price:20}],method:'炸',meal:'午',allergen:'无',status:'停用',source:'味养创新',weightBasePrice:'7.78',weightVipPrice:'7.00',crowd:[{name:'成人',level:'推荐'},{name:'糖尿病人群',level:'慎食'},{name:'高血脂人群',level:'适量'}],crowdNote:'糖尿病人群慎食,含糖量高',
|
||||
{id:'DISH005',name:'糖醋里脊',icon:'🍖',category:'荤菜',tags:['高糖'],specs:[{name:'标准份',weight:180,price:14,cleanPrice:10,cleanSale:false,isDefault:true},{name:'大份',weight:280,price:20,cleanPrice:14,cleanSale:false}],method:'炸',meal:'午',allergen:'无',status:'停用',source:'味养创新',weightBasePrice:'7.78',weightVipPrice:'7.00',crowd:[{name:'成人',level:'推荐'},{name:'糖尿病人群',level:'慎食'},{name:'高血脂人群',level:'适量'}],crowdNote:'糖尿病人群慎食,含糖量高',
|
||||
composition:[{name:'猪里脊肉',netType:'里脊丝',amount:120,pct:'66.7%',state:'净菜',type:'主材',allergen:'无',note:'—'},{name:'淀粉',netType:'淀粉糊',amount:20,pct:'11.1%',state:'原料',type:'辅材',allergen:'无',note:'挂糊'},{name:'白糖',netType:'糖浆',amount:25,pct:'13.9%',state:'原料',type:'调料',allergen:'无',note:'糖醋汁'},{name:'食醋',netType:'调味汁',amount:15,pct:'8.3%',state:'原料',type:'调料',allergen:'无',note:'糖醋汁'}],
|
||||
nutri:{calorie:420,protein:22.4,carb:38.2,fat:18.6,vitC:1.2,mineral:28,fiber:0.6,sodium:620,nutriGrade:'未达标',note:'铁1.8mg'},
|
||||
cook:{mainMethod:'炸',subMethod:'炒',heat:'大火',duration:15,oil:50,salt:1,temp:'180',output:180,steps:7},
|
||||
@@ -353,7 +361,10 @@ function renderDetail(){
|
||||
function renderBasic(d){
|
||||
var specRows = (d.specs||[]).map(function(s){
|
||||
var statusHtml = s.isDefault ? '<span class="tag tag-blue" style="font-size:11px;">默认</span>' : '';
|
||||
return '<tr><td>'+s.name+'</td><td>'+s.weight+'</td><td>'+s.price.toFixed(2)+'</td><td>'+statusHtml+'</td></tr>';
|
||||
var cleanPrice = (s.cleanPrice!==undefined && s.cleanPrice!==null) ? parseFloat(s.cleanPrice).toFixed(2) : '—';
|
||||
var cleanSaleActive = s.cleanSale === true;
|
||||
var cleanSaleHtml = '<div class="sale-toggle'+(cleanSaleActive?' active':'')+'" onclick="toggleCleanSale(this)"><span class="sale-toggle__switch"></span><span class="sale-toggle__label">'+(cleanSaleActive?'上架':'下架')+'</span></div>';
|
||||
return '<tr><td>'+s.name+'</td><td>'+s.weight+'</td><td>'+s.price.toFixed(2)+'</td><td>'+cleanPrice+'</td><td>'+cleanSaleHtml+'</td><td>'+statusHtml+'</td></tr>';
|
||||
}).join('');
|
||||
return `<div class="info-section"><div class="info-section__title">基本信息 <span><a class="link" href="din-dish-add.html?mode=edit&tab=0">编辑</a></span></div>
|
||||
<div class="info-grid">
|
||||
@@ -371,7 +382,7 @@ function renderBasic(d){
|
||||
<div style="display:flex;flex-wrap:wrap;gap:8px;margin-bottom:12px;">${(d.crowd||[]).map(function(c){return '<div style="display:flex;align-items:center;gap:4px;"><span style="font-size:var(--font-sm);">'+c.name+'</span>'+levelTag(c.level)+'</div>';}).join('')}</div>
|
||||
${d.crowdNote?'<div style="font-size:var(--font-sm);color:var(--text-secondary);background:#FFFBE6;padding:8px 12px;border-radius:var(--radius-sm);border:1px solid #FFE58F;">⚠️ '+d.crowdNote+'</div>':''}</div>
|
||||
<div class="info-section"><div class="info-section__title">📐 餐品规格(共 ${(d.specs||[]).length} 项)</div>
|
||||
<table class="info-table spec-detail-table"><thead><tr><th>规格</th><th>单位重量(g)</th><th>售价(元/份)</th><th>状态</th></tr></thead><tbody>${specRows}</tbody></table></div>
|
||||
<table class="info-table spec-detail-table"><thead><tr><th>规格</th><th>单位重量(g)</th><th>餐品售价(元/份)</th><th>净菜包售价(元/份)</th><th>外售净菜包</th><th>状态</th></tr></thead><tbody>${specRows}</tbody></table></div>
|
||||
<div class="info-section"><div class="info-section__title">📷 菜品展示</div>
|
||||
<div class="media-grid">
|
||||
<div class="media-card"><div class="media-card__thumb">图片</div></div>
|
||||
@@ -487,6 +498,13 @@ function renderVideos(d){
|
||||
|
||||
// 侧边栏折叠
|
||||
function toggleSubgroup(header){header.parentElement.classList.toggle('open');}
|
||||
|
||||
// 切换外售净菜包上架/下架状态
|
||||
function toggleCleanSale(el){
|
||||
var active = el.classList.toggle('active');
|
||||
var label = el.querySelector('.sale-toggle__label');
|
||||
if(label) label.textContent = active ? '上架' : '下架';
|
||||
}
|
||||
(function(){var a=document.querySelector('.sidebar-item.active');if(!a)return;var s=a.closest('.sidebar-subgroup');if(s)s.classList.add('open');})();
|
||||
|
||||
// 初始化
|
||||
|
||||
@@ -835,8 +835,6 @@ function buildProfileHTML(name, p) {
|
||||
</div>`,
|
||||
dynamic: `<div class="profile-grid">
|
||||
<div class="profile-field"><span class="profile-field__label">日均运动量</span><span class="profile-field__value">${p.exercise}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">体重趋势</span><span class="profile-field__value">${p.weightTrend}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">体脂率</span><span class="profile-field__value">${p.bodyFat}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">静息心率</span><span class="profile-field__value">${p.heartRate} bpm</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">平均睡眠</span><span class="profile-field__value">${p.sleep}</span></div>
|
||||
<div class="profile-field"><span class="profile-field__label">压力指数</span><span class="profile-field__value">${p.stress}</span></div>
|
||||
|
||||
Reference in New Issue
Block a user