feat: 新增今日食谱页、做-社区模块重构及子页面,多页面交互优化

- 新增 eat-recipe-today.html(今日食谱展示,含日期栏、餐次Tab、分类菜品卡片)
- 新增 eat-cart.html(购物车页面)
- 新增 make-ranking.html(创作排行榜,含本周/本月/总榜切换)
- 新增 make-share.html(分享赚钱,含收益卡片、奖励规则、收益明细)
- 新增 make-popular.html(热门创作列表,含分类筛选)
- 重构 make-home.html(Banner + 四宫格导航 + 热门创作)
- 优化 make-create.html(支持封面图片/视频上传、步骤媒体上传)
- 优化 make-follow.html(食谱详情支持视频播放按钮、步骤媒体展示)
- 优化 eat-recipe.html(查看食谱跳转、扫码点餐提示)
- 同步更新多个小程序页面交互及后台管理页面样式

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
冯普
2026-05-14 17:33:50 +08:00
co-authored by Claude Opus 4.6
parent db4eda7ef9
commit 3e29c5ea43
19 changed files with 2404 additions and 290 deletions
+111 -3
View File
@@ -97,6 +97,29 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.upload-area:hover{border-color:var(--primary);color:var(--primary);}
.upload-area__icon{font-size:36px;margin-bottom:8px;}
.upload-area__text{font-size:var(--font-sm);}
/* 餐品规格区域 */
.spec-section{margin-top:16px;padding-top:16px;border-top:1px solid var(--border);}
.spec-section__header{display:flex;align-items:center;margin-bottom:8px;}
.spec-section__title{font-size:var(--font-sm);font-weight:600;color:var(--text-primary);display:flex;align-items:center;gap:6px;}
.spec-table{width:100%;border-collapse:collapse;font-size:12px;}
.spec-table th{background:#FAFAFA;padding:6px 10px;text-align:left;color:var(--text-secondary);font-weight:500;border-bottom:1px solid var(--border);}
.spec-table td{padding:6px 10px;border-bottom:1px solid #F0F0F0;color:var(--text-primary);}
.spec-table tr:hover{background:#F8FBFF;}
.spec-add-row:hover{background:var(--primary-light) !important;}
.spec-add-row td{color:var(--primary);cursor:pointer;border-bottom:none;padding:5px 10px;}
.spec-edit-row .form-input{height:28px;font-size:12px;padding:0 8px;}
.tag-default{background:var(--primary-light);color:var(--primary);padding:1px 8px;border-radius:10px;font-size:var(--font-xs);font-weight:500;}
.spec-toggle{display:inline-flex;align-items:center;gap:6px;cursor:pointer;user-select:none;}
.spec-toggle__switch{width:32px;height:18px;background:#D9D9D9;border-radius:9px;position:relative;transition:background .2s;flex-shrink:0;}
.spec-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);}
.spec-toggle.active .spec-toggle__switch{background:var(--primary);}
.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;}
.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;}
.btn-text--default{color:var(--text-secondary);}.btn-text--default:hover{background:#F5F5F5;color:var(--text-primary);}
/* 操作列固定右侧 */
thead th:last-child,tbody td.td-actions{position:sticky;right:0;background:#fff;box-shadow:-4px 0 8px rgba(0,0,0,0.04);z-index:2;white-space:nowrap;}
thead th:last-child{background:#FAFAFA;}
@@ -192,11 +215,48 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<div class="form-grid">
<div class="form-group"><label class="form-label">餐品名称<span class="required">*</span></label><input class="form-input" type="text" placeholder="请输入餐品名称"></div>
<div class="form-group"><label class="form-label">餐品分类<span class="required">*</span></label><select class="form-select"><option>请选择</option><option>主食</option><option>荤菜</option><option>素菜</option><option>汤品</option><option>小吃</option></select></div>
<div class="form-group"><label class="form-label">规格</label><select class="form-select"><option>标准份</option><option>小份</option><option>大份</option></select></div>
<div class="form-group"><label class="form-label">单位重量(g)<span class="required">*</span></label><input class="form-input" type="number" placeholder="请输入重量"></div>
<div class="form-group"><label class="form-label">售价(元/份)<span class="required">*</span></label><input class="form-input" type="number" placeholder="请输入售价"></div>
<div class="form-group"><label class="form-label">烹饪方法</label><select class="form-select"><option>请选择</option><option></option><option></option><option></option><option></option><option>凉拌</option><option></option><option></option></select></div>
<div class="form-group"><label class="form-label">适用餐次</label><input class="form-input" type="text" placeholder="早/午/晚"></div>
</div>
<!-- 餐品规格 -->
<div class="spec-section">
<div class="spec-section__header">
<div class="spec-section__title">📐 餐品规格<span class="required">*</span></div>
</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>
<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>
<td>大份</td>
<td>500</td>
<td>20.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>
</tbody>
</table>
</div>
<div class="form-grid" style="margin-top:16px;">
<div class="form-group"><label class="form-label">过敏原</label><input class="form-input" type="text" placeholder="无则填无"></div>
<div class="form-group"><label class="form-label">餐品标签</label><input class="form-input" type="text" placeholder="低脂/高蛋白/素食,逗号分隔"></div>
<div class="form-group"><label class="form-label">上架状态</label><select class="form-select"><option>上架</option><option>下架</option></select></div>
@@ -356,6 +416,54 @@ function submitForm(){ alert('提交成功!'); window.location.href='din-dish-
function openIngredientDialog(){document.getElementById('ingredientDialog').classList.add('open');}
function closeIngredientDialog(){document.getElementById('ingredientDialog').classList.remove('open');}
function toggleSubgroup(header){header.parentElement.classList.toggle('open');}
/* 规格管理 */
function addSpecRow(addRow){
/* 如果已有编辑行,不重复添加 */
if(document.querySelector('.spec-edit-row')) return;
var tr=document.createElement('tr');
tr.className='spec-edit-row';
tr.innerHTML='<td><input class="form-input" type="text" placeholder="规格名称"></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>';
addRow.parentNode.insertBefore(tr,addRow);
tr.querySelector('input').focus();
}
function confirmSpec(btn){
var row=btn.closest('tr');
var inputs=row.querySelectorAll('input');
var name=inputs[0].value.trim();
var weight=inputs[1].value.trim();
var price=inputs[2].value.trim();
if(!name||!weight||!price){alert('请填写完整信息');return;}
/* 将编辑行转为数据行 */
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>';
}
function cancelSpec(btn){
btn.closest('tr').remove();
}
function toggleDefault(el){
var tbody=document.getElementById('specBody');
/* 清除所有开关状态 */
tbody.querySelectorAll('.spec-toggle').forEach(function(t){ t.classList.remove('active'); });
/* 激活当前开关 */
el.classList.add('active');
}
function removeSpec(btn){
var row=btn.closest('tr');
var wasDefault=row.querySelector('.spec-toggle.active');
row.remove();
/* 如果删除的是默认规格,将第一条数据行设为默认 */
if(wasDefault){
var first=document.querySelector('#specBody tr:not(.spec-add-row):not(.spec-edit-row) .spec-toggle');
if(first) first.classList.add('active');
}
}
</script>
</body>
</html>
+14 -9
View File
@@ -113,6 +113,8 @@ body{font-family:-apple-system,BlinkMacSystemFont,'PingFang SC','Microsoft YaHei
.info-table td{padding:10px 12px;border-bottom:1px solid var(--border);color:var(--text-primary);}
.info-table tr:last-child td{border-bottom:none;}
.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;}
/* 图片/视频网格 */
.media-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;}
@@ -274,7 +276,7 @@ tbody tr:hover td.td-actions{background:#F8FBFF;}
<script>
// 餐品数据
const DISHES = [
{id:'DISH001',name:'红烧肉',icon:'🥩',category:'荤菜',tags:['高蛋白'],spec:'标准份',weight:200,price:12,method:'炖',meal:'午/晚',allergen:'无',status:'上架',
{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:'上架',
composition:[{name:'猪五花肉',cat:'畜肉类',amount:160,pct:'80%',state:'净菜',main:true,allergen:'无',note:'—'},{name:'生姜',cat:'调料',amount:5,pct:'2.5%',state:'净菜',main:false,allergen:'无',note:'—'},{name:'生抽',cat:'调料',amount:15,pct:'7.5%',state:'原料',main:false,allergen:'含麸质',note:'酱油'},{name:'冰糖',cat:'调料',amount:10,pct:'5%',state:'原料',main:false,allergen:'无',note:'上色提味'},{name:'料酒',cat:'调料',amount:10,pct:'5%',state:'原料',main:false,allergen:'无',note:'去腥'}],
nutri:{calorie:385,protein:18.2,fat:28.6,carb:12.4,sodium:486,gi:52,giLevel:'中GI',gl:18.6,si:68,orac:420,purine:120,cholesterol:86,transFat:0.2,pyramid:'畜禽肉蛋水产'},
cook:{mainMethod:'炖',subMethod:'煎',heat:'中火→小火',duration:45,oil:15,salt:3,temp:'100→80',output:200,steps:6},
@@ -282,7 +284,7 @@ const DISHES = [
color:{mainColor:'红褐色',desc:'色泽红亮,油润光泽,肉质饱满',cause:'酱油上色,焦糖化反应',grade:'优',crowd:['成人','老年人'],level:'适量',note:'老年人消化负担稍重'},
texture:{mainTexture:'软烂',chew:'易',digest:'中',desc:'肥而不腻,入口即化,胶质丰富',crowd:['成人','老年人','儿童'],level:'适量',suggest:'儿童控制脂肪摄入'}
},
{id:'DISH002',name:'清炒时蔬',icon:'🥬',category:'素菜',tags:['低脂','素食'],spec:'标准份',weight:150,price:6,method:'炒',meal:'早/午/晚',allergen:'无',status:'上架',
{id:'DISH002',name:'清炒时蔬',icon:'🥬',category:'素菜',tags:['低脂','素食'],specs:[{name:'标准份',weight:150,price:6,isDefault:true},{name:'小份',weight:100,price:4}],method:'炒',meal:'早/午/晚',allergen:'无',status:'上架',
composition:[{name:'时令青菜',cat:'蔬菜类',amount:120,pct:'80%',state:'净菜',main:true,allergen:'无',note:'—'},{name:'蒜末',cat:'调料',amount:5,pct:'3.3%',state:'净菜',main:false,allergen:'无',note:'—'},{name:'食用油',cat:'油脂类',amount:8,pct:'5.3%',state:'原料',main:false,allergen:'无',note:'—'},{name:'食盐',cat:'调料',amount:2,pct:'1.3%',state:'原料',main:false,allergen:'无',note:'—'}],
nutri:{calorie:68,protein:2.1,fat:3.2,carb:8.6,sodium:186,gi:15,giLevel:'低GI',gl:2.1,si:142,orac:2860,purine:18,cholesterol:0,transFat:0,pyramid:'蔬菜'},
cook:{mainMethod:'炒',subMethod:'—',heat:'大火',duration:5,oil:8,salt:2,temp:'200',output:150,steps:4},
@@ -290,7 +292,7 @@ const DISHES = [
color:{mainColor:'翠绿色',desc:'翠绿鲜亮,色泽均匀,叶片完整',cause:'叶绿素保留,大火快炒',grade:'优',crowd:['全人群'],level:'推荐',note:'—'},
texture:{mainTexture:'嫩脆',chew:'易',digest:'易',desc:'清脆爽口,纤维感适中,汁水丰富',crowd:['全人群','老年人'],level:'推荐',suggest:'老年人可炒至更软'}
},
{id:'DISH003',name:'番茄鸡蛋汤',icon:'🍅',category:'汤品',tags:['低卡'],spec:'标准份',weight:300,price:5,method:'煮',meal:'午/晚',allergen:'含蛋类',status:'上架',
{id:'DISH003',name:'番茄鸡蛋汤',icon:'🍅',category:'汤品',tags:['低卡'],specs:[{name:'标准份',weight:300,price:5,isDefault:true}],method:'煮',meal:'午/晚',allergen:'含蛋类',status:'上架',
composition:[{name:'番茄',cat:'蔬菜类',amount:150,pct:'50%',state:'净菜',main:true,allergen:'无',note:'—'},{name:'鸡蛋',cat:'蛋类',amount:60,pct:'20%',state:'原料',main:true,allergen:'含蛋类',note:'—'},{name:'食用油',cat:'油脂类',amount:5,pct:'1.7%',state:'原料',main:false,allergen:'无',note:'—'},{name:'食盐',cat:'调料',amount:2,pct:'0.7%',state:'原料',main:false,allergen:'无',note:'—'}],
nutri:{calorie:45,protein:3.8,fat:2.1,carb:4.2,sodium:280,gi:35,giLevel:'低GI',gl:4.8,si:128,orac:1240,purine:42,cholesterol:186,transFat:0,pyramid:'蔬菜+蛋类'},
cook:{mainMethod:'煮',subMethod:'炒',heat:'中火',duration:12,oil:5,salt:2,temp:'100',output:300,steps:5},
@@ -298,7 +300,7 @@ const DISHES = [
color:{mainColor:'橙红色',desc:'汤色橙红,蛋花嫩黄,色彩鲜艳',cause:'番茄红素,蛋黄色素',grade:'优',crowd:['全人群','儿童'],level:'推荐',note:'—'},
texture:{mainTexture:'嫩滑',chew:'易',digest:'易',desc:'汤汁鲜美,蛋花嫩滑,易于消化',crowd:['全人群','婴幼儿','术后恢复'],level:'推荐',suggest:'—'}
},
{id:'DISH004',name:'米饭',icon:'🍚',category:'主食',tags:['主食'],spec:'标准份',weight:200,price:3,method:'蒸',meal:'早/午/晚',allergen:'无',status:'上架',
{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:'上架',
composition:[{name:'大米',cat:'谷薯类',amount:100,pct:'100%',state:'原料',main:true,allergen:'无',note:'—'}],
nutri:{calorie:232,protein:4.8,fat:0.6,carb:51.2,sodium:3,gi:83,giLevel:'高GI',gl:33.2,si:52,orac:180,purine:0,cholesterol:0,transFat:0,pyramid:'谷薯杂豆'},
cook:{mainMethod:'蒸',subMethod:'—',heat:'大火→中火',duration:30,oil:0,salt:0,temp:'100',output:200,steps:2},
@@ -306,7 +308,7 @@ const DISHES = [
color:{mainColor:'乳白色',desc:'洁白晶莹,颗粒饱满,有光泽',cause:'淀粉糊化,水分均匀',grade:'优',crowd:['全人群'],level:'推荐',note:'—'},
texture:{mainTexture:'软糯',chew:'易',digest:'易',desc:'颗粒分明,软糯适中,不粘不散',crowd:['全人群','老年人'],level:'推荐',suggest:'老年人可煮软一些'}
},
{id:'DISH005',name:'糖醋里脊',icon:'🍖',category:'荤菜',tags:['高糖'],spec:'标准份',weight:180,price:14,method:'炸',meal:'午',allergen:'无',status:'下架',
{id:'DISH005',name:'糖醋里脊',icon:'🍖',category:'荤菜',tags:['高糖'],specs:[{name:'标准份',weight:180,price:14,isDefault:true},{name:'大份',weight:280,price:20}],method:'炸',meal:'午',allergen:'无',status:'下架',
composition:[{name:'猪里脊肉',cat:'畜肉类',amount:120,pct:'66.7%',state:'净菜',main:true,allergen:'无',note:'—'},{name:'淀粉',cat:'谷薯类',amount:20,pct:'11.1%',state:'原料',main:false,allergen:'无',note:'挂糊'},{name:'白糖',cat:'调料',amount:25,pct:'13.9%',state:'原料',main:false,allergen:'无',note:'糖醋汁'},{name:'食醋',cat:'调料',amount:15,pct:'8.3%',state:'原料',main:false,allergen:'无',note:'糖醋汁'}],
nutri:{calorie:420,protein:22.4,fat:18.6,carb:38.2,sodium:620,gi:68,giLevel:'中GI',gl:28.4,si:45,orac:380,purine:98,cholesterol:72,transFat:0.8,pyramid:'畜禽肉蛋水产'},
cook:{mainMethod:'炸',subMethod:'炒',heat:'大火',duration:15,oil:50,salt:1,temp:'180',output:180,steps:7},
@@ -345,19 +347,22 @@ 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>';
}).join('');
return `<div class="info-section"><div class="info-section__title">基本信息 <span><span class="link">编辑</span></span></div>
<div class="info-grid">
<div class="info-cell"><div class="info-cell__label">餐品编号</div><div class="info-cell__value">${d.id}</div></div>
<div class="info-cell"><div class="info-cell__label">餐品分类</div><div class="info-cell__value">${d.category}</div></div>
<div class="info-cell"><div class="info-cell__label">规格</div><div class="info-cell__value">${d.spec}</div></div>
<div class="info-cell"><div class="info-cell__label">单位重量</div><div class="info-cell__value">${d.weight}g</div></div>
<div class="info-cell"><div class="info-cell__label">售价</div><div class="info-cell__value">¥${d.price.toFixed(1)}</div></div>
<div class="info-cell"><div class="info-cell__label">烹饪方法</div><div class="info-cell__value">${d.method}</div></div>
<div class="info-cell"><div class="info-cell__label">适用餐次</div><div class="info-cell__value">${d.meal}</div></div>
<div class="info-cell"><div class="info-cell__label">过敏原</div><div class="info-cell__value">${d.allergen}</div></div>
<div class="info-cell"><div class="info-cell__label">餐品标签</div><div class="info-cell__value">${d.tags.map(t=>'<span class="tag tag-blue">'+t+'</span>').join('')}</div></div>
<div class="info-cell"><div class="info-cell__label">上架状态</div><div class="info-cell__value"><span class="tag tag-${d.status==='上架'?'green':'gray'}">${d.status}</span></div></div>
</div></div>`;
</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>`;
}
function renderComposition(d){