console
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>我的减脂饮食记录</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.8/dist/chart.umd.min.js"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: '#22c55e',
warn: '#f97316',
danger: '#ef4444'
}
}
}
}
</script>
<style>
.tab-active { @apply border-b-2 border-primary text-primary font-medium; }
input[type="number"]::-webkit-inner-spin-button,
input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }
</style>
</head>
<body class="bg-gray-50 text-gray-800 max-w-md mx-auto pb-24">
<header class="bg-primary text-white p-4 sticky top-0 z-10 shadow">
<h1 class="text-xl font-bold text-center"><i class="fa fa-cutlery mr-2"></i>减脂饮食规划</h1>
</header>
<!-- Tab导航 -->
<div class="flex bg-white shadow-sm">
<button onclick="switchTab('home')" id="tab-home" class="flex-1 py-3 text-center tab-active">首页</button>
<button onclick="switchTab('food')" id="tab-food" class="flex-1 py-3 text-center text-gray-500">记饮食</button>
<button onclick="switchTab('weight')" id="tab-weight" class="flex-1 py-3 text-center text-gray-500">体重</button>
<button onclick="switchTab('setting')" id="tab-setting" class="flex-1 py-3 text-center text-gray-500">设置</button>
</div>
<!-- 首页面板 -->
<div id="page-home" class="p-4">
<div class="bg-white rounded-xl p-4 shadow mb-4">
<div class="flex justify-between items-center mb-2">
<span class="font-semibold">今日热量</span>
<span id="today-tag" class="text-sm px-2 py-1 rounded bg-green-100 text-green-700">普通日</span>
</div>
<div class="text-3xl font-bold my-2">
<span id="cal-eat">0</span>
<span class="text-base font-normal text-gray-500"> / <span id="cal-goal">2000</span> kcal</span>
</div>
<div class="w-full bg-gray-200 rounded-full h-3">
<div id="cal-bar" class="bg-primary h-3 rounded-full transition-all" style="width:0%"></div>
</div>
<div class="mt-2 text-sm text-gray-500">剩余:<span id="cal-left">2000</span> kcal</div>
</div>
<div class="bg-white rounded-xl p-4 shadow mb-4">
<h3 class="font-semibold mb-3">今日摄入明细</h3>
<div id="today-list" class="space-y-2 text-sm max-h-64 overflow-y-auto">
<div class="text-gray-400 text-center py-4">还没有记录食物</div>
</div>
</div>
<div class="grid grid-cols-2 gap-3">
<button onclick="setDayType('normal')" class="bg-white p-3 rounded-xl shadow text-center">
<i class="fa fa-circle-o text-primary mr-1"></i>普通减脂日
</button>
<button onclick="setDayType('light')" class="bg-white p-3 rounded-xl shadow text-center">
<i class="fa fa-leaf text-warn mr-1"></i>周六轻食日
</button>
<button onclick="setDayType('feast')" class="bg-white p-3 rounded-xl shadow text-center col-span-2">
<i class="fa fa-fire text-danger mr-1"></i>周日自助放纵餐
</button>
</div>
</div>
<!-- 记饮食面板 -->
<div id="page-food" class="p-4 hidden">
<div class="bg-white rounded-xl p-4 shadow mb-4">
<h3 class="font-semibold mb-3">快速添加(你的常用食物)</h3>
<div class="grid grid-cols-2 gap-2">
<button onclick="addFood('去皮鸭腿(110g)', 209, 26.6, 5.7)" class="border border-gray-200 p-2 rounded-lg text-sm">去皮鸭腿</button>
<button onclick="addFood('瘦手切羊肉(100g)', 150, 22, 6)" class="border border-gray-200 p-2 rounded-lg text-sm">瘦羊肉100g</button>
<button onclick="addFood('毛肚百叶(100g)',70,14,1)" class="border border-gray-200 p-2 rounded-lg text-sm">毛肚百叶100g</button>
<button onclick="addFood('大虾(100g)',90,20,1)" class="border border-gray-200 p-2 rounded-lg text-sm">大虾100g</button>
<button onclick="addFood('西兰花(100g)',34,2.8,0.4)" class="border border-gray-200 p-2 rounded-lg text-sm">西兰花</button>
<button onclick="addFood('糙米饭(100g)',116,2.6,0.8)" class="border border-gray-200 p-2 rounded-lg text-sm">糙米饭</button>
<button onclick="addFood('水煮鸡蛋1个',70,6,5)" class="border border-gray-200 p-2 rounded-lg text-sm">水煮蛋</button>
<button onclick="addFood('烧饼1/4个',70,2,4)" class="border border-gray-200 p-2 rounded-lg text-sm">1/4烧饼</button>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow">
<h3 class="font-semibold mb-3">自定义录入</h3>
<div class="space-y-3">
<input id="food-name" placeholder="食物名字" class="w-full border rounded-lg p-2">
<div class="grid grid-cols-2 gap-2">
<input id="food-kcal" placeholder="热量(kcal)" type="number" class="border rounded-lg p-2">
<input id="food-pro" placeholder="蛋白质(g)" type="number" class="border rounded-lg p-2">
</div>
<button onclick="customAdd()" class="w-full bg-primary text-white py-2 rounded-lg">添加这条记录</button>
</div>
</div>
</div>
<!-- 体重面板 -->
<div id="page-weight" class="p-4 hidden">
<div class="bg-white rounded-xl p-4 shadow mb-4">
<h3 class="font-semibold mb-3">记录今日体重</h3>
<div class="flex gap-2">
<input id="weight-val" placeholder="例如92.0" type="number" step="0.1" class="flex-1 border rounded-lg p-2">
<button onclick="saveWeight()" class="bg-primary text-white px-4 rounded-lg">保存</button>
</div>
</div>
<div class="bg-white rounded-xl p-4 shadow p-4">
<canvas id="weightChart"></canvas>
</div>
<div id="weight-list" class="mt-4 space-y-1 text-sm"></div>
</div>
<!-- 设置面板 -->
<div id="page-setting" class="p-4 hidden">
<div class="bg-white rounded-xl p-4 shadow space-y-4">
<div>
<label class="text-sm">每日目标热量 kcal</label>
<input id="goal-cal" type="number" class="w-full border rounded-lg p-2 mt-1" value="2000">
</div>
<div>
<label class="text-sm">身高 cm</label>
<input id="set-height" type="number" class="w-full border rounded-lg p-2 mt-1" value="180">
</div>
<div>
<label class="text-sm">当前体重 kg</label>
<input id="set-weight" type="number" step="0.1" class="w-full border rounded-lg p-2 mt-1" value="92">
</div>
<div>
<label class="text-sm">目标体重 kg</label>
<input id="set-target" type="number" step="0.1" class="w-full border rounded-lg p-2 mt-1" value="75">
</div>
<button onclick="saveSetting()" class="w-full bg-primary text-white py-2 rounded-lg">保存设置</button>
<button onclick="clearAllData()" class="w-full bg-red-50 text-red-600 py-2 rounded-lg">清空全部数据(谨慎!)</button>
</div>
</div>
<script>
// 本地存储key
const KEY_SET = "diet_setting";
const KEY_TODAY = "diet_today";
const KEY_WEIGHT = "diet_weight";
let pageNow = "home";
let weightChart = null;
// 初始化
function init(){
loadSetting();
loadToday();
loadWeight();
renderHome();
renderWeightList();
drawChart();
}
// 切换页面
function switchTab(p){
pageNow = p;
["home","food","weight","setting"].forEach(k=>{
document.getElementById("page-"+k).classList.add("hidden");
document.getElementById("tab-"+k).classList.remove("tab-active");
document.getElementById("tab-"+k).classList.add("text-gray-500");
})
document.getElementById("page-"+p).classList.remove("hidden");
document.getElementById("tab-"+p).classList.add("tab-active");
document.getElementById("tab-"+p).classList.remove("text-gray-500");
if(p==="weight") drawChart();
}
// 设置日期标记
function setDayType(type){
const map = {normal:"普通减脂日",light:"周六轻食日",feast:"周日自助放纵餐"};
localStorage.setItem("daytype",type);
document.getElementById("today-tag").innerText = map[type];
if(type==="feast"){
document.getElementById("today-tag").className="text-sm px-2 py-1 rounded bg-red-100 text-red-700";
}else if(type==="light"){
document.getElementById("today-tag").className="text-sm px-2 py-1 rounded bg-orange-100 text-orange-700";
}else{
document.getElementById("today-tag").className="text-sm px-2 py-1 rounded bg-green-100 text-green-700";
}
}
// 加载设置
function loadSetting(){
let s = JSON.parse(localStorage.getItem(KEY_SET)||'{"cal":2000,"h":180,"w":92,"tw":75}');
document.getElementById("goal-cal").value = s.cal;
document.getElementById("set-height").value = s.h;
document.getElementById("set-weight").value = s.w;
document.getElementById("set-target").value = s.tw;
}
function saveSetting(){
let obj = {
cal: Number(document.getElementById("goal-cal").value),
h: Number(document.getElementById("set-height").value),
w: Number(document.getElementById("set-weight").value),
tw: Number(document.getElementById("set-target").value)
}
localStorage.setItem(KEY_SET, JSON.stringify(obj));
renderHome();
alert("✅ 设置已保存");
}
// 今日饮食
let todayList = [];
function loadToday(){
const today = new Date().toLocaleDateString();
let raw = JSON.parse(localStorage.getItem(KEY_TODAY)||"{}");
if(raw.date !== today) {
todayList = [];
saveToday();
}else{
todayList = raw.list;
}
}
function saveToday(){
localStorage.setItem(KEY_TODAY, JSON.stringify({
date: new Date().toLocaleDateString(),
list: todayList
}))
}
function addFood(name, kcal, pro, fat){
todayList.push({name,kcal,pro,fat,time:new Date().toLocaleTimeString()});
saveToday();
renderHome();
alert(`✅ 添加:${name}`);
}
function customAdd(){
let n = document.getElementById("food-name").value.trim();
let k = Number(document.getElementById("food-kcal").value);
let p = Number(document.getElementById("food-pro").value||0);
if(!n || !k) return alert("名字和热量必填");
addFood(n,k,p,0);
document.getElementById("food-name").value="";
document.getElementById("food-kcal").value="";
document.getElementById("food-pro").value="";
}
function delFood(idx){
todayList.splice(idx,1);
saveToday();
renderHome();
}
function renderHome(){
const set = JSON.parse(localStorage.getItem(KEY_SET)||'{"cal":2000}');
const goal = set.cal;
let total = todayList.reduce((sum,item)=>sum+Number(item.kcal),0);
document.getElementById("cal-eat").innerText = total;
document.getElementById("cal-goal").innerText = goal;
document.getElementById("cal-left").innerText = Math.max(0, goal-total);
document.getElementById("cal-bar").style.width = Math.min(100, total/goal*100)+"%";
let html = "";
if(todayList.length === 0) html = `<div class="text-gray-400 text-center py-4">还没有记录食物</div>`;
else {
todayList.forEach((it,i)=>{
html += `<div class="flex justify-between border-b py-1">
<span>${it.name} <span class="text-gray-400">${it.time}</span></span>
<span>${it.kcal}kcal <button onclick="delFood(${i})" class="text-red-400 ml-2"><i class="fa fa-times"></i></button></span>
</div>`
})
}
document.getElementById("today-list").innerHTML = html;
}
// 体重记录
let weightArr = [];
function loadWeight(){
weightArr = JSON.parse(localStorage.getItem(KEY_WEIGHT)||"[]");
}
function saveWeight(){
let w = Number(document.getElementById("weight-val").value);
if(!w) return alert("填写体重");
weightArr.push({
d: new Date().toLocaleDateString(),
val: w
})
localStorage.setItem(KEY_WEIGHT, JSON.stringify(weightArr));
document.getElementById("weight-val").value="";
renderWeightList();
drawChart();
alert("✅ 体重已保存");
}
function renderWeightList(){
let html = "";
[...weightArr].reverse().forEach(it=>{
html += `<div class="flex justify-between border-b py-1">
<span>${it.d}</span><span>${it.val} kg</span>
</div>`
})
document.getElementById("weight-list").innerHTML = html;
}
function drawChart(){
const ctx = document.getElementById("weightChart").getContext("2d");
const labels = weightArr.map(x=>x.d);
const data = weightArr.map(x=>x.val);
if(weightChart) weightChart.destroy();
weightChart = new Chart(ctx,{
type:"line",
data:{
labels: labels,
datasets:[{
label:"体重kg",
data:data,
borderColor:"#22c55e",
fill:false,
tension:0.2
}]
},
options:{responsive:true,maintainAspectRatio:true}
})
}
// 清空全部
function clearAllData(){
if(!confirm("确定清空所有饮食、体重记录?无法恢复!")) return;
localStorage.removeItem(KEY_TODAY);
localStorage.removeItem(KEY_WEIGHT);
localStorage.removeItem("daytype");
todayList = []; weightArr=[];
renderHome();renderWeightList();drawChart();
alert("✅ 全部清空");
}
window.onload = init;
</script>
</body>
</html>