feat: 支持用户按餐次自定义营养素配比

This commit is contained in:
fengpu
2026-09-08 15:25:36 +08:00
parent 0bc9a33aec
commit 55819e077a
@@ -172,6 +172,14 @@
margin-top: 6px; resize: none; line-height: 1.5; font-family: inherit;
}
.m-textarea:focus { border-color: #1677ff; background: #fff; }
/* 餐次配比 */
.ratio-bar { display: flex; height: 10px; border-radius: 5px; overflow: hidden; background: #f0f0f0; margin-bottom: 12px; }
.ratio-bar .ratio-seg { height: 100%; }
.ratio-list { display: flex; }
.ratio-list .ratio-item { flex: 1; display: flex; align-items: center; gap: 4px; font-size: 12px; }
.ratio-list .ratio-item .r-dot { width: 8px; height: 8px; border-radius: 50%; flex-shrink: 0; }
.ratio-list .ratio-item .r-name { color: #999; }
.ratio-list .ratio-item .r-val { color: #333; font-weight: 600; }
</style>
</head>
<body>
@@ -381,6 +389,26 @@
</div>
</div>
<!-- 9. 餐次配比 可编辑 -->
<div class="section" id="ratioSection" onclick="openRatioModal()" 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="ratio-bar" id="viewRatioBar">
<span class="ratio-seg" style="width:30%; background:#FFB84C;"></span>
<span class="ratio-seg" style="width:40%; background:#52C41A;"></span>
<span class="ratio-seg" style="width:30%; background:#1677FF;"></span>
<span class="ratio-seg" style="width:0%; background:#D9D9D9;"></span>
</div>
<div class="ratio-list">
<div class="ratio-item"><span class="r-dot" style="background:#FFB84C;"></span><span class="r-name">早餐</span><span class="r-val" id="viewRatioBreakfast">30%</span></div>
<div class="ratio-item"><span class="r-dot" style="background:#52C41A;"></span><span class="r-name">午餐</span><span class="r-val" id="viewRatioLunch">40%</span></div>
<div class="ratio-item"><span class="r-dot" style="background:#1677FF;"></span><span class="r-name">晚餐</span><span class="r-val" id="viewRatioDinner">30%</span></div>
<div class="ratio-item"><span class="r-dot" style="background:#D9D9D9;"></span><span class="r-name">加餐</span><span class="r-val" id="viewRatioSnack">0%</span></div>
</div>
</div>
</div>
<div class="home-indicator"></div>
@@ -574,6 +602,35 @@
</div>
</div>
<!-- ========== 餐次配比编辑弹窗 ========== -->
<div class="modal-mask" id="ratioModal">
<div class="modal-panel" onclick="event.stopPropagation()">
<div class="modal-header">
<span class="m-cancel" onclick="closeModal('ratioModal')">取消</span>
<span class="m-title">编辑餐次配比</span>
<span class="m-save" onclick="saveRatioModal()">保存</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="inputRatioBreakfast" value="30"><span class="mg-unit">%</span></span>
</div>
<div class="m-goal-row">
<span class="mg-label">午餐</span>
<span class="mg-input-wrap"><input type="number" id="inputRatioLunch" value="40"><span class="mg-unit">%</span></span>
</div>
<div class="m-goal-row">
<span class="mg-label">晚餐</span>
<span class="mg-input-wrap"><input type="number" id="inputRatioDinner" value="30"><span class="mg-unit">%</span></span>
</div>
<div class="m-goal-row">
<span class="mg-label">加餐</span>
<span class="mg-input-wrap"><input type="number" id="inputRatioSnack" value="0"><span class="mg-unit">%</span></span>
</div>
</div>
</div>
</div>
</div>
<script>
/* ========== 通用弹窗控制 ========== */
@@ -725,6 +782,42 @@
alert('已保存(原型演示)');
}
/* ========== 餐次配比 ========== */
var ratioMeals = [
{ inputId: 'inputRatioBreakfast', viewValId: 'viewRatioBreakfast', color: '#FFB84C' },
{ inputId: 'inputRatioLunch', viewValId: 'viewRatioLunch', color: '#52C41A' },
{ inputId: 'inputRatioDinner', viewValId: 'viewRatioDinner', color: '#1677FF' },
{ inputId: 'inputRatioSnack', viewValId: 'viewRatioSnack', color: '#D9D9D9' }
];
function openRatioModal() {
document.getElementById('ratioModal').classList.add('active');
}
function saveRatioModal() {
var vals = [];
var sum = 0;
ratioMeals.forEach(function(m) {
var v = parseFloat(document.getElementById(m.inputId).value) || 0;
vals.push(v);
sum += v;
});
if (Math.abs(sum - 100) > 0.01) {
alert('四餐占比之和需等于 100%,当前为 ' + (Math.round(sum * 100) / 100) + '%');
return;
}
var bar = document.getElementById('viewRatioBar');
bar.innerHTML = '';
vals.forEach(function(v, i) {
var seg = document.createElement('span');
seg.className = 'ratio-seg';
seg.style.width = v + '%';
seg.style.background = ratioMeals[i].color;
bar.appendChild(seg);
document.getElementById(ratioMeals[i].viewValId).textContent = v + '%';
});
closeModal('ratioModal');
alert('已保存(原型演示)');
}
/* ========== 通用回写:将编辑态标签同步到页面展示区 ========== */
// viewId: 展示区容器id; groupId: 编辑态分组id; cls: 展示态span的class; asText: true则拼成文本而非标签
function syncGroupBack(viewId, groupId, cls, asText) {
@@ -748,7 +841,7 @@
}
/* ========== 点击遮罩层空白处关闭弹窗 ========== */
['bodyModal','diseaseModal','tasteModal','tabooModal','dishModal','momModal'].forEach(function(id) {
['bodyModal','diseaseModal','tasteModal','tabooModal','dishModal','momModal','ratioModal'].forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('click', function() { closeModal(id); });
});