feat: 管理端场所/分类管理增强及小程序端交互优化

- 后台营养管理:场所新增/编辑页重构(营业时段/图片/资质)、食材及餐品分类管理弹窗、从已有食材复制
- 营养管理小程序:净菜包订单按状态差异化展示、时间选择器交互重构、新增收货地址页、移除营养目标分区
- CHANGELOG 更新至 2026-07-23

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-07-23 16:49:25 +08:00
co-authored by Claude Opus 4.7
parent bab86f72f3
commit ea8239debf
19 changed files with 1911 additions and 190 deletions
@@ -92,16 +92,42 @@
.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;
/* 期望配送时间:下拉框风格 */
.time-picker-trigger {
display: flex; align-items: center; justify-content: space-between;
height: 38px; padding: 0 12px; border-radius: 8px;
border: 1px solid #e8e8e8; background: #fff; cursor: pointer;
}
.date-chip.active, .time-chip.active {
background: #1677ff; color: #fff; font-weight: 600;
.tpt-text { font-size: 13px; color: #333; }
.tpt-arrow { font-size: 10px; color: #999; transition: transform 0.2s; }
.tpt-arrow.open { transform: rotate(180deg); }
.time-picker-panel {
display: none; margin-top: 6px; gap: 8px;
}
.time-picker-panel.show { display: flex; }
.tp-date-col {
width: 88px; flex-shrink: 0; display: flex; flex-direction: column; gap: 4px;
}
.tp-date-card {
padding: 7px 6px; border-radius: 6px; border: 1px solid #e8e8e8;
text-align: center; cursor: pointer; background: #fff; transition: all 0.15s;
}
.tp-date-card.active { border-color: #1677ff; background: #e6f4ff; }
.tp-date-card .tp-date-week { font-size: 10px; color: #999; margin-bottom: 2px; }
.tp-date-card.active .tp-date-week { color: #1677ff; font-weight: 600; }
.tp-date-card .tp-date-day { font-size: 12px; color: #333; font-weight: 600; }
.tp-date-card.active .tp-date-day { color: #1677ff; }
.tp-time-col {
flex: 1; max-height: 220px; overflow-y: auto;
display: flex; flex-direction: column; gap: 2px;
border: 1px solid #e8e8e8; border-radius: 6px; padding: 4px 6px;
}
.tp-time-col::-webkit-scrollbar { display: none; }
.tp-time-item {
padding: 6px 10px; border-radius: 6px; font-size: 12px; color: #333;
cursor: pointer; text-align: center; transition: all 0.15s;
}
.tp-time-item.active { background: #1677ff; color: #fff; font-weight: 600; }
/* 地址卡片 */
.address-card, .pickup-card {
padding: 12px; border-radius: 8px; border: 1px solid #e8e8e8; background: #fafafa;
@@ -225,8 +251,6 @@
</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>
@@ -243,20 +267,43 @@
</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 class="time-picker-trigger" id="timePickerTrigger">
<span class="tpt-text" id="tptText">4月30日 周五 11:00-12:00</span>
<span class="tpt-arrow" id="tptArrow"></span>
</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 class="time-picker-panel" id="timePickerPanel">
<div class="tp-date-col">
<div class="tp-date-card active" data-week="周五" data-day="4月30日">
<div class="tp-date-week">周五</div>
<div class="tp-date-day">4月30日</div>
</div>
<div class="tp-date-card" data-week="周六" data-day="5月1日">
<div class="tp-date-week">周六</div>
<div class="tp-date-day">5月1日</div>
</div>
<div class="tp-date-card" data-week="周日" data-day="5月2日">
<div class="tp-date-week">周日</div>
<div class="tp-date-day">5月2日</div>
</div>
</div>
<div class="tp-time-col">
<div class="tp-time-item">07:00-08:00</div>
<div class="tp-time-item">08:00-09:00</div>
<div class="tp-time-item">09:00-10:00</div>
<div class="tp-time-item">10:00-11:00</div>
<div class="tp-time-item active">11:00-12:00</div>
<div class="tp-time-item">12:00-13:00</div>
<div class="tp-time-item">13:00-14:00</div>
<div class="tp-time-item">14:00-15:00</div>
<div class="tp-time-item">15:00-16:00</div>
<div class="tp-time-item">16:00-17:00</div>
<div class="tp-time-item">17:00-18:00</div>
<div class="tp-time-item">18:00-19:00</div>
<div class="tp-time-item">19:00-20:00</div>
</div>
</div>
</div>
<!-- 配送地址(仅 delivery,支持选择/新增) -->
@@ -371,7 +418,8 @@
var orderAmount = document.getElementById('orderAmount');
var actionBtns = document.getElementById('actionBtns');
/* 取货方式切换:联动地址组/自提组显示 */
/* 取货方式切换:联动地址组/自提组 + 时间标签文本 */
var timeLabel = document.querySelectorAll('.fulfill-card .fg-label')[1];
document.querySelectorAll('.pickup-method').forEach(function(m) {
m.addEventListener('click', function() {
document.querySelectorAll('.pickup-method').forEach(function(x) { x.classList.remove('active'); });
@@ -379,22 +427,63 @@
var isDelivery = m.dataset.method === 'delivery';
document.getElementById('addressGroup').classList.toggle('hidden', !isDelivery);
document.getElementById('pickupGroup').classList.toggle('hidden', isDelivery);
/* 切换标签文本 */
if (isDelivery) {
timeLabel.innerHTML = '期望配送时间 <span class="required">*</span>';
} else {
timeLabel.innerHTML = '自提时间 <span class="required">*</span>';
}
});
});
/* 日期 chip 单选切换 */
document.querySelectorAll('.date-chip').forEach(function(c) {
c.addEventListener('click', function() {
document.querySelectorAll('.date-chip').forEach(function(x) { x.classList.remove('active'); });
/* 下拉面板展开/收起 */
var timePickerTrigger = document.getElementById('timePickerTrigger');
var timePickerPanel = document.getElementById('timePickerPanel');
var tptText = document.getElementById('tptText');
var tptArrow = document.getElementById('tptArrow');
timePickerTrigger.addEventListener('click', function(e) {
e.stopPropagation();
var isOpen = timePickerPanel.classList.toggle('show');
if (isOpen) { tptArrow.classList.add('open'); }
else { tptArrow.classList.remove('open'); }
});
/* 点击面板外部关闭 */
document.addEventListener('click', function(e) {
if (!timePickerTrigger.contains(e.target) && !timePickerPanel.contains(e.target)) {
timePickerPanel.classList.remove('show');
tptArrow.classList.remove('open');
}
});
/* 更新触发区显示文本 */
function updateTriggerText() {
var activeDate = document.querySelector('.tp-date-card.active');
var activeTime = document.querySelector('.tp-time-item.active');
var week = activeDate ? activeDate.dataset.week : '';
var day = activeDate ? activeDate.dataset.day : '';
var time = activeTime ? activeTime.textContent : '';
tptText.textContent = day + ' ' + week + ' ' + time;
}
/* 日期卡片单选切换 */
document.querySelectorAll('.tp-date-card').forEach(function(c) {
c.addEventListener('click', function(e) {
e.stopPropagation();
document.querySelectorAll('.tp-date-card').forEach(function(x) { x.classList.remove('active'); });
c.classList.add('active');
updateTriggerText();
});
});
/* 时段 chip 单选切换 */
document.querySelectorAll('.time-chip').forEach(function(c) {
c.addEventListener('click', function() {
document.querySelectorAll('.time-chip').forEach(function(x) { x.classList.remove('active'); });
/* 时段列表项单选切换 */
document.querySelectorAll('.tp-time-item').forEach(function(c) {
c.addEventListener('click', function(e) {
e.stopPropagation();
document.querySelectorAll('.tp-time-item').forEach(function(x) { x.classList.remove('active'); });
c.classList.add('active');
updateTriggerText();
});
});
@@ -473,7 +562,7 @@
/* 净菜包订单:改为"确认订单"页,隐藏取餐码,展示履约表单 */
successIcon.textContent = '📝';
successTitle.textContent = '确认订单信息';
successDesc.textContent = '请补充履约信息后提交订单';
successDesc.textContent = '请先选择配送方式后再提交订单';
pickupBlock.classList.add('hidden');
fulfillBlock.classList.remove('hidden');
orderItems.innerHTML =
@@ -68,9 +68,15 @@
.menu-item .food-icon {
width: 56px; height: 56px; border-radius: 10px; background: #f5f5f5;
display: flex; align-items: center; justify-content: center; font-size: 28px; flex-shrink: 0;
cursor: pointer;
}
.menu-item .food-info { flex: 1; min-width: 0; }
.menu-item .food-name { font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.menu-item .food-name {
font-size: 14px; font-weight: 600; display: flex; align-items: center; gap: 4px; flex-wrap: wrap;
cursor: pointer;
}
.menu-item .food-name:hover { color: #1677ff; }
.menu-item .food-desc { cursor: pointer; }
.food-tag {
font-size: 10px; font-weight: 600; padding: 1px 5px; border-radius: 3px;
white-space: nowrap; line-height: 16px;
@@ -236,7 +242,7 @@
<div class="menu-item" data-price="22">
<div class="food-icon">🍗</div>
<div class="food-info">
<div class="food-name">宫保鸡丁净菜包</div>
<div class="food-name">宫保鸡丁</div>
<div class="food-desc">腌好鸡丁+配料包 · 约300g · 285kcal</div>
<div class="food-bottom">
<span class="food-price">¥22</span>
@@ -248,7 +254,7 @@
<div class="menu-item" data-price="10">
<div class="food-icon">🍅</div>
<div class="food-info">
<div class="food-name">番茄炒蛋净菜包</div>
<div class="food-name">番茄炒蛋</div>
<div class="food-desc">切好番茄+调好蛋液 · 约250g · 168kcal</div>
<div class="food-bottom">
<span class="food-price">¥10</span>
@@ -260,7 +266,7 @@
<div class="menu-item" data-price="26">
<div class="food-icon">🍖</div>
<div class="food-info">
<div class="food-name">红烧肉净菜包</div>
<div class="food-name">红烧肉</div>
<div class="food-desc">炖好五花肉+酱料包 · 约350g · 395kcal</div>
<div class="food-bottom">
<span class="food-price">¥26</span>
@@ -272,7 +278,7 @@
<div class="menu-item" data-price="28">
<div class="food-icon">🐟</div>
<div class="food-info">
<div class="food-name">清蒸鱼净菜包</div>
<div class="food-name">清蒸鱼</div>
<div class="food-desc">处理净草鱼+葱姜丝 · 约220g · 142kcal</div>
<div class="food-bottom">
<span class="food-price">¥28</span>
@@ -284,7 +290,7 @@
<div class="menu-item" data-price="35">
<div class="food-icon">🥗</div>
<div class="food-info">
<div class="food-name">低脂控糖套餐净菜包</div>
<div class="food-name">低脂控糖套餐</div>
<div class="food-desc">鸡胸+糙米饭+西兰花 · 约400g · 320kcal</div>
<div class="food-bottom">
<span class="food-price">¥35</span>
@@ -296,7 +302,7 @@
<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-name">2-3人家庭套餐</div>
<div class="food-desc">3菜1汤半成品 · 约1.2kg · 1200kcal</div>
<div class="food-bottom">
<span class="food-price">¥68</span>
@@ -420,6 +426,27 @@
/* 初始化:购物车归零 */
updateCart();
/* 菜品点击查看详情:餐品和净菜包统一跳转 eat-dish-detail.html */
var detailTarget = { 'panel-meal': 'eat-dish-detail.html', 'panel-clean': 'eat-dish-detail.html' };
document.querySelectorAll('.menu-item').forEach(function(item) {
/* 根据 menu-item 所在面板解析目标页 */
var panel = item.closest('.order-layout');
var target = panel && detailTarget[panel.id] ? detailTarget[panel.id] : 'eat-dish-detail.html';
var triggerHandler = function(e) {
/* 避免点到加减按钮区域 */
if (e.target.closest('.food-bottom')) return;
location.href = target;
};
/* 图标、名称、描述可点击跳转,加减按钮不受影响 */
var icon = item.querySelector('.food-icon');
var name = item.querySelector('.food-name');
var desc = item.querySelector('.food-desc');
[icon, name, desc].forEach(function(el) {
if (el) el.addEventListener('click', triggerHandler);
});
});
</script>
</body>
</html>
@@ -0,0 +1,426 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>收货地址 | 智能餐养小程序</title>
<style>
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
background: #2a2a2a; display: flex; justify-content: center; align-items: flex-start;
min-height: 100vh; font-family: -apple-system, BlinkMacSystemFont, 'PingFang SC', 'Helvetica Neue', sans-serif;
padding: 24px 0 40px;
}
.phone-shell {
width: 390px; height: 844px; background: #fff; border-radius: 44px;
box-shadow: 0 20px 60px rgba(0,0,0,0.3), inset 0 0 0 2px #e0e0e0;
overflow: hidden; position: relative; display: flex; flex-direction: column;
}
.status-bar {
height: 44px; background: #fff; display: flex; align-items: center;
justify-content: space-between; padding: 0 24px; font-size: 12px; font-weight: 600; flex-shrink: 0;
}
.status-bar .time { font-size: 15px; font-weight: 700; }
.status-bar .icons { display: flex; gap: 6px; align-items: center; }
.nav-bar { height: 44px; background: #fff; display: flex; align-items: center; padding: 0 16px; border-bottom: 0.5px solid #f0f0f0; flex-shrink: 0; position: relative; }
.nav-bar .back { font-size: 22px; color: #1677ff; cursor: pointer; text-decoration: none; line-height: 1; }
.nav-bar .title { position: absolute; left: 50%; transform: translateX(-50%); font-size: 17px; font-weight: 600; }
.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; }
.page-content { flex: 1; overflow-y: auto; background: #f5f5f5; padding-bottom: 16px; }
.page-content::-webkit-scrollbar { display: none; }
/* 地址卡片 */
.addr-card {
margin: 12px 16px 0; background: #fff; border-radius: 12px; padding: 14px;
position: relative; box-shadow: 0 1px 4px rgba(0,0,0,0.04);
}
.addr-card .ac-top { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.addr-card .ac-name { font-size: 15px; font-weight: 600; color: #333; }
.addr-card .ac-phone { font-size: 13px; color: #666; }
.addr-card .ac-default {
font-size: 10px; padding: 1px 6px; border-radius: 8px; background: #fff7e6; color: #fa8c16; font-weight: 600;
}
.addr-card .ac-detail { font-size: 13px; color: #555; line-height: 1.6; padding-right: 70px; }
.addr-card .ac-actions {
position: absolute; right: 12px; bottom: 12px; display: flex; gap: 6px;
}
.addr-card .ac-btn {
font-size: 12px; padding: 3px 10px; border-radius: 12px; border: none; cursor: pointer;
background: #f5f5f5; color: #666;
}
.addr-card .ac-btn.primary { background: #e6f4ff; color: #1677ff; }
/* 编辑表单 */
.addr-form {
margin: 10px 0 0; padding: 12px; border-radius: 8px; background: #fafafa; border: 1px solid #e8e8e8;
display: none;
}
.addr-form.show { display: block; }
.addr-form .form-row { padding: 8px 0; border-bottom: 0.5px solid #f0f0f0; }
.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: #fff; outline: none;
}
.addr-form .form-input:focus { border-color: #1677ff; }
.addr-form .form-textarea {
width: 100%; min-height: 56px; border-radius: 6px; border: 1px solid #e8e8e8;
padding: 8px 10px; font-size: 13px; background: #fff; outline: none; resize: none; font-family: inherit;
}
.addr-form .form-textarea:focus { border-color: #1677ff; }
.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; }
/* 新增按钮 */
.add-btn-wrap { margin: 16px 16px 0; }
.add-addr-btn {
width: 100%; padding: 14px 0; border-radius: 12px; border: 1.5px dashed #1677ff;
background: #fff; color: #1677ff; font-size: 14px; font-weight: 600; cursor: pointer;
display: flex; align-items: center; justify-content: center; gap: 4px;
}
/* 空状态 */
.empty-state { text-align: center; padding: 60px 20px; color: #ccc; }
.empty-state .empty-icon { font-size: 48px; margin-bottom: 12px; }
.empty-state .empty-text { font-size: 14px; }
.hidden { display: none !important; }
</style>
</head>
<body>
<div class="phone-shell">
<div class="status-bar">
<span class="time">09:41</span>
<div class="icons"><span>📶</span><span>WiFi</span><span>🔋</span></div>
</div>
<div class="nav-bar">
<a class="back" href="me-home.html"></a>
<span class="title">收货地址</span>
</div>
<div class="page-content" id="pageContent">
<!-- 地址列表 -->
<div class="addr-card" data-id="1">
<div class="ac-top">
<span class="ac-name">张三</span>
<span class="ac-phone">138****6688</span>
<span class="ac-default">默认</span>
</div>
<div class="ac-detail">渝北区龙湖路123号4栋1单元1801</div>
<div class="ac-actions">
<button class="ac-btn primary" data-action="edit">编辑</button>
<button class="ac-btn" data-action="delete">删除</button>
</div>
<!-- 编辑表单 -->
<div class="addr-form">
<div class="form-row">
<div class="form-label">收货人 <span class="required">*</span></div>
<input class="form-input" value="张三" placeholder="请输入收货人姓名">
</div>
<div class="form-row">
<div class="form-label">手机号 <span class="required">*</span></div>
<input class="form-input" value="138****6688" placeholder="请输入11位手机号">
</div>
<div class="form-row">
<div class="form-label">所在地区 <span class="required">*</span></div>
<input class="form-input" value="重庆市 渝北区" placeholder="省 / 市 / 区" readonly>
</div>
<div class="form-row">
<div class="form-label">详细地址 <span class="required">*</span></div>
<textarea class="form-textarea" placeholder="街道、楼牌号等">渝北区龙湖路123号4栋1单元1801</textarea>
</div>
<div class="form-row form-switch">
<span>设为默认收货地址</span>
<button class="switch-toggle on"></button>
</div>
<div class="addr-form-actions">
<button class="btn btn-cancel" data-action="cancel">取消</button>
<button class="btn btn-save" data-action="save">保存</button>
</div>
</div>
</div>
<div class="addr-card" data-id="2">
<div class="ac-top">
<span class="ac-name">张三</span>
<span class="ac-phone">138****6688</span>
</div>
<div class="ac-detail">南岸区江南大道28号写字楼12层</div>
<div class="ac-actions">
<button class="ac-btn primary" data-action="edit">编辑</button>
<button class="ac-btn" data-action="delete">删除</button>
</div>
<div class="addr-form">
<div class="form-row">
<div class="form-label">收货人 <span class="required">*</span></div>
<input class="form-input" value="张三" placeholder="请输入收货人姓名">
</div>
<div class="form-row">
<div class="form-label">手机号 <span class="required">*</span></div>
<input class="form-input" value="138****6688" placeholder="请输入11位手机号">
</div>
<div class="form-row">
<div class="form-label">所在地区 <span class="required">*</span></div>
<input class="form-input" value="重庆市 南岸区" placeholder="省 / 市 / 区" readonly>
</div>
<div class="form-row">
<div class="form-label">详细地址 <span class="required">*</span></div>
<textarea class="form-textarea" placeholder="街道、楼牌号等">南岸区江南大道28号写字楼12层</textarea>
</div>
<div class="form-row form-switch">
<span>设为默认收货地址</span>
<button class="switch-toggle"></button>
</div>
<div class="addr-form-actions">
<button class="btn btn-cancel" data-action="cancel">取消</button>
<button class="btn btn-save" data-action="save">保存</button>
</div>
</div>
</div>
<div class="addr-card" data-id="3">
<div class="ac-top">
<span class="ac-name">李四</span>
<span class="ac-phone">139****1234</span>
</div>
<div class="ac-detail">渝北区黄山大道中段55号2栋802</div>
<div class="ac-actions">
<button class="ac-btn primary" data-action="edit">编辑</button>
<button class="ac-btn" data-action="delete">删除</button>
</div>
<div class="addr-form">
<div class="form-row">
<div class="form-label">收货人 <span class="required">*</span></div>
<input class="form-input" value="李四" placeholder="请输入收货人姓名">
</div>
<div class="form-row">
<div class="form-label">手机号 <span class="required">*</span></div>
<input class="form-input" value="139****1234" placeholder="请输入11位手机号">
</div>
<div class="form-row">
<div class="form-label">所在地区 <span class="required">*</span></div>
<input class="form-input" value="重庆市 渝北区" placeholder="省 / 市 / 区" readonly>
</div>
<div class="form-row">
<div class="form-label">详细地址 <span class="required">*</span></div>
<textarea class="form-textarea" placeholder="街道、楼牌号等">渝北区黄山大道中段55号2栋802</textarea>
</div>
<div class="form-row form-switch">
<span>设为默认收货地址</span>
<button class="switch-toggle"></button>
</div>
<div class="addr-form-actions">
<button class="btn btn-cancel" data-action="cancel">取消</button>
<button class="btn btn-save" data-action="save">保存</button>
</div>
</div>
</div>
<!-- 新增按钮 -->
<div class="add-btn-wrap" id="addBtnWrap">
<button class="add-addr-btn" id="showAddBtn"> 新增收货地址</button>
</div>
<!-- 新增地址表单 -->
<div class="addr-card hidden" id="addCard">
<div class="ac-top">
<span class="ac-name" style="color:#999;">新地址</span>
</div>
<div class="addr-form show" id="addForm">
<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="addDefaultToggle"></button>
</div>
<div class="addr-form-actions">
<button class="btn btn-cancel" id="addCancelBtn">取消</button>
<button class="btn btn-save" id="addSaveBtn">保存</button>
</div>
</div>
</div>
</div>
<div class="home-indicator"></div>
</div>
<script>
/* 编辑/删除按钮事件委托 */
document.getElementById('pageContent').addEventListener('click', function(e) {
var actionBtn = e.target.closest('[data-action]');
if (!actionBtn) {
/* 点击开关切换 */
var toggle = e.target.closest('.switch-toggle');
if (toggle) { toggle.classList.toggle('on'); }
return;
}
var card = actionBtn.closest('.addr-card');
var action = actionBtn.dataset.action;
if (action === 'edit') {
/* 展开/收起编辑表单 */
var form = card.querySelector('.addr-form');
var isOpen = form.classList.contains('show');
/* 关闭所有其他表单 */
document.querySelectorAll('.addr-form.show').forEach(function(f) { f.classList.remove('show'); });
if (!isOpen) { form.classList.add('show'); }
} else if (action === 'delete') {
/* 原型演示:直接移除卡片 */
if (confirm('确定要删除该收货地址吗?')) {
card.remove();
checkEmpty();
}
} else if (action === 'cancel') {
/* 取消编辑:关闭表单 */
card.querySelector('.addr-form').classList.remove('show');
} else if (action === 'save') {
/* 保存编辑:同步表单数据到卡片并关闭 */
var form = card.querySelector('.addr-form');
var inputs = form.querySelectorAll('.form-input, .form-textarea');
var name = inputs[0].value || '未命名';
var phone = inputs[1].value || '';
var area = inputs[2].value || '';
var detail = inputs[3].value || '';
var isDefault = form.querySelector('.switch-toggle').classList.contains('on');
/* 更新卡片显示 */
card.querySelector('.ac-name').textContent = name;
card.querySelector('.ac-phone').textContent = phone;
card.querySelector('.ac-detail').textContent = area ? area + ' ' + detail : detail;
/* 默认地址标识 */
var defaultTag = card.querySelector('.ac-default');
if (isDefault) {
/* 其他卡片移除默认 */
document.querySelectorAll('.ac-default').forEach(function(t) { t.style.display = 'none'; });
if (defaultTag) { defaultTag.style.display = ''; }
else {
var tag = document.createElement('span');
tag.className = 'ac-default';
tag.textContent = '默认';
card.querySelector('.ac-top').appendChild(tag);
}
} else {
if (defaultTag) defaultTag.style.display = 'none';
}
form.classList.remove('show');
}
});
/* 显示新增表单 */
document.getElementById('showAddBtn').addEventListener('click', function() {
document.getElementById('addCard').classList.remove('hidden');
document.getElementById('addBtnWrap').classList.add('hidden');
});
/* 新增表单默认开关 */
document.getElementById('addDefaultToggle').addEventListener('click', function() {
this.classList.toggle('on');
});
/* 取消新增 */
document.getElementById('addCancelBtn').addEventListener('click', function() {
document.getElementById('addCard').classList.add('hidden');
document.getElementById('addBtnWrap').classList.remove('hidden');
/* 清空表单 */
var form = document.getElementById('addForm');
form.querySelectorAll('.form-input, .form-textarea').forEach(function(el) { el.value = ''; });
form.querySelector('.switch-toggle').classList.remove('on');
});
/* 保存新增 */
document.getElementById('addSaveBtn').addEventListener('click', function() {
var form = document.getElementById('addForm');
var inputs = form.querySelectorAll('.form-input, .form-textarea');
var name = inputs[0].value || '新地址';
var phone = inputs[1].value || '';
var area = inputs[2].value || '';
var detail = inputs[3].value || '';
var isDefault = form.querySelector('.switch-toggle').classList.contains('on');
/* 生成新卡片 */
var html = '<div class="addr-card" data-id="' + Date.now() + '">'
+ '<div class="ac-top">'
+ '<span class="ac-name">' + name + '</span>'
+ '<span class="ac-phone">' + phone + '</span>'
+ (isDefault ? '<span class="ac-default">默认</span>' : '')
+ '</div>'
+ '<div class="ac-detail">' + (area ? area + ' ' : '') + detail + '</div>'
+ '<div class="ac-actions">'
+ '<button class="ac-btn primary" data-action="edit">编辑</button>'
+ '<button class="ac-btn" data-action="delete">删除</button>'
+ '</div>'
+ '<div class="addr-form">'
+ '<div class="form-row"><div class="form-label">收货人 <span class="required">*</span></div><input class="form-input" value="' + name + '" placeholder="请输入收货人姓名"></div>'
+ '<div class="form-row"><div class="form-label">手机号 <span class="required">*</span></div><input class="form-input" value="' + phone + '" placeholder="请输入11位手机号"></div>'
+ '<div class="form-row"><div class="form-label">所在地区 <span class="required">*</span></div><input class="form-input" value="' + area + '" placeholder="省 / 市 / 区" readonly></div>'
+ '<div class="form-row"><div class="form-label">详细地址 <span class="required">*</span></div><textarea class="form-textarea" placeholder="街道、楼牌号等">' + detail + '</textarea></div>'
+ '<div class="form-row form-switch"><span>设为默认收货地址</span><button class="switch-toggle' + (isDefault ? ' on' : '') + '"></button></div>'
+ '<div class="addr-form-actions"><button class="btn btn-cancel" data-action="cancel">取消</button><button class="btn btn-save" data-action="save">保存</button></div>'
+ '</div>'
+ '</div>';
/* 如果设为默认,移除其他地址的默认标记 */
if (isDefault) {
document.querySelectorAll('.ac-default').forEach(function(t) { t.style.display = 'none'; });
}
/* 插入到新增按钮之前 */
document.getElementById('addBtnWrap').insertAdjacentHTML('beforebegin', html);
/* 隐藏新增表单并重置 */
document.getElementById('addCard').classList.add('hidden');
document.getElementById('addBtnWrap').classList.remove('hidden');
inputs.forEach(function(el) { el.value = ''; });
form.querySelector('.switch-toggle').classList.remove('on');
checkEmpty();
});
/* 检查地址列表是否为空 */
function checkEmpty() {
var cards = document.querySelectorAll('.addr-card:not(#addCard)');
if (cards.length === 0) {
var emptyHtml = '<div class="empty-state" id="emptyHint"><div class="empty-icon">📭</div><div class="empty-text">暂无收货地址</div></div>';
document.getElementById('addBtnWrap').insertAdjacentHTML('beforebegin', emptyHtml);
} else {
var hint = document.getElementById('emptyHint');
if (hint) hint.remove();
}
}
</script>
</body>
</html>
@@ -381,17 +381,6 @@
</div>
</div>
<!-- 9. 营养目标 保留 -->
<div class="section" id="goalSection" onclick="openGoalModal()" 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="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>
<div class="goal-item"><span class="g-label">饮水量</span><span class="g-value" id="viewGoalWater">≥2000ml</span></div>
</div>
</div>
<div class="home-indicator"></div>
@@ -585,34 +574,6 @@
</div>
</div>
<!-- ========== 营养目标编辑弹窗 ========== -->
<div class="modal-mask" id="goalModal">
<div class="modal-panel" onclick="event.stopPropagation()">
<div class="modal-header">
<span class="m-cancel" onclick="closeModal('goalModal')">取消</span>
<span class="m-title">编辑营养目标</span>
<span class="m-save" onclick="saveGoalModal()">保存</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="inputCalorie" value="2000"><span class="mg-unit">kcal</span></span>
</div>
<div class="m-goal-row">
<span class="mg-label">蛋白质(≥)</span>
<span class="mg-input-wrap"><input type="number" id="inputProtein" value="60"><span class="mg-unit">g</span></span>
</div>
<div class="m-goal-row">
<span class="mg-label">膳食纤维(≥)</span>
<span class="mg-input-wrap"><input type="number" id="inputFiber" value="25"><span class="mg-unit">g</span></span>
</div>
<div class="m-goal-row">
<span class="mg-label">饮水量(≥)</span>
<span class="mg-input-wrap"><input type="number" id="inputWater" value="2000"><span class="mg-unit">ml</span></span>
</div>
</div>
</div>
</div>
</div>
<script>
/* ========== 通用弹窗控制 ========== */
@@ -764,21 +725,6 @@
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';
var fib = document.getElementById('inputFiber').value || '0';
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';
closeModal('goalModal');
alert('已保存(原型演示)');
}
/* ========== 通用回写:将编辑态标签同步到页面展示区 ========== */
// viewId: 展示区容器id; groupId: 编辑态分组id; cls: 展示态span的class; asText: true则拼成文本而非标签
function syncGroupBack(viewId, groupId, cls, asText) {
@@ -802,7 +748,7 @@
}
/* ========== 点击遮罩层空白处关闭弹窗 ========== */
['bodyModal','diseaseModal','tasteModal','tabooModal','dishModal','momModal','goalModal'].forEach(function(id) {
['bodyModal','diseaseModal','tasteModal','tabooModal','dishModal','momModal'].forEach(function(id) {
var el = document.getElementById(id);
if (el) el.addEventListener('click', function() { closeModal(id); });
});
@@ -133,6 +133,7 @@
<div class="menu-group">
<a class="menu-item" href="me-health.html"><span class="m-icon">💚</span><span class="m-label">健康档案</span><span class="m-arrow"></span></a>
<a class="menu-item" href="me-orders.html"><span class="m-icon">📋</span><span class="m-label">我的订单</span><span class="m-badge">2</span><span class="m-arrow"></span></a>
<a class="menu-item" href="me-address.html"><span class="m-icon">📍</span><span class="m-label">收货地址</span><span class="m-arrow"></span></a>
<a class="menu-item" href="me-favorites.html"><span class="m-icon"></span><span class="m-label">收藏食谱</span><span class="m-arrow"></span></a>
<a class="menu-item" href="me-wallet.html"><span class="m-icon">💰</span><span class="m-label">我的余额</span><span class="m-arrow"></span></a>
<a class="menu-item" href="me-vip.html"><span class="m-icon">👑</span><span class="m-label">会员中心</span><span class="m-arrow"></span></a>
@@ -56,6 +56,7 @@
.ing-name { font-size: 12px; font-weight: 500; color: #444; }
.ing-code { font-size: 9px; color: #bbb; font-family: monospace; margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ing-ok { font-size: 10px; padding: 1px 5px; border-radius: 5px; background: #f6ffed; color: #52c41a; flex-shrink: 0; white-space: nowrap; }
.ing-role { font-size: 10px; padding: 1px 5px; border-radius: 4px; flex-shrink: 0; white-space: nowrap; background: #f5f5f5; color: #999; }
.ing-trace { padding: 3px 8px; border-radius: 8px; border: 1px solid #1677ff; background: #fff; color: #1677ff; font-size: 10px; cursor: pointer; flex-shrink: 0; white-space: nowrap; text-decoration: none; }
/* 营养建议 */
.advice-card { background: #fff; border-radius: 12px; padding: 12px 14px; margin: 0 16px 24px; }
@@ -124,16 +125,11 @@
<div class="oh-stat"><div class="sv" style="color:#1677ff">3</div><div class="sl">菜品数</div></div>
<div class="oh-stat"><div class="sv" style="color:#555">442</div><div class="sl">总热量kcal</div></div>
</div>
<div class="oh-tags">
<span class="oh-tag" style="background:#e6f4ff;color:#1677ff">点餐取餐</span>
<span class="oh-tag" style="background:#f5f5f5;color:#666">A区中餐线</span>
<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="sec-title">📦 配送信息</div>
<div class="info-row">
<span class="ir-label">取货方式</span>
<span class="ir-value">🚚 配送到家</span>
@@ -293,7 +289,22 @@
}
var type = getQuery('type') === 'clean' ? 'clean' : 'meal';
/* 净菜包订单状态:delivering=待配送 / shipped=已发货 / done=已完成;缺省按待配送处理 */
var rawStatus = getQuery('status');
var status = ['delivering', 'shipped', 'done'].indexOf(rawStatus) >= 0 ? rawStatus : 'delivering';
/* 是否展示食材来源与溯源按钮:仅 已发货 / 已完成 可见 */
var showTrace = status === 'shipped' || status === 'done';
if (type === 'clean') {
/* 状态徽标:文案与配色随 status 切换 */
var badgeMap = {
delivering: { text: '🚚 待配送', bg: '#e6f4ff', color: '#1677ff' },
shipped: { text: '🚚 配送中', bg: '#fff7e6', color: '#fa8c16' },
done: { text: '✅ 已完成', bg: '#f6ffed', color: '#52c41a' }
};
var b = badgeMap[status];
/* 替换订单头部:净菜包订单基本信息 */
document.getElementById('orderHeader').innerHTML =
'<div class="oh-top">'
@@ -301,26 +312,62 @@
+ '<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>'
+ '<span class="oh-badge" style="background:' + b.bg + ';color:' + b.color + ';">' + b.text + '</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');
/* 替换菜品明细:餐品 → 净菜包明细 */
/* 替换菜品明细:餐品 → 净菜包明细;待配送状态下不展示食材来源/溯源 */
var dishTitle = showTrace ? '净菜包明细 · 食材 · 溯源' : '净菜包明细';
/* 宫保鸡丁净菜包:食材明细(已发货/已完成 有溯源按钮,待配送无溯源按钮;均含克重) */
var gongBaoIngRows = [
{ name: '鸡胸肉', weight: '150g', code: 'NC-PROC-JBR-20260422-01', role: '主材' },
{ name: '花生米', weight: '30g', code: 'ST-EX-HS05-PT-HSMI-050K-20260420-001', role: '辅材' }
];
var gongBaoIng = showTrace
? '<div class="ing-section">'
+ '<div class="ing-label">食材来源</div>'
+ gongBaoIngRows.map(function(r) {
return '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">' + r.name + ' ' + r.weight + '</div><div class="ing-code">' + r.code + '</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>';
}).join('')
+ '</div>'
: '<div class="ing-section">'
+ '<div class="ing-label">食材明细</div>'
+ gongBaoIngRows.map(function(r) {
return '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">' + r.name + ' ' + r.weight + '</div></div><span class="ing-role">' + r.role + '</span></div>';
}).join('')
+ '</div>';
/* 低脂控糖套餐净菜包:食材明细(同上规则) */
var lowFatIngRows = [
{ name: '鸡胸肉', weight: '150g', code: 'NC-PROC-JBR-20260422-01', role: '主材' },
{ name: '西兰花', weight: '80g', code: 'ST-EX-LY01-VG-XLHU-080K-20260416-001', role: '辅材' },
{ name: '糙米', weight: '120g', code: 'ST-EX-LY03-DG-CAMI-500K-20260413-002', role: '主材' }
];
var lowFatIng = showTrace
? '<div class="ing-section">'
+ '<div class="ing-label">食材来源</div>'
+ lowFatIngRows.map(function(r) {
return '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">' + r.name + ' ' + r.weight + '</div><div class="ing-code">' + r.code + '</div></div><span class="ing-ok">✅合格</span><a class="ing-trace" href="trace-detail.html">🔗溯源</a></div>';
}).join('')
+ '</div>'
: '<div class="ing-section">'
+ '<div class="ing-label">食材明细</div>'
+ lowFatIngRows.map(function(r) {
return '<div class="ing-row"><div class="ing-dot"></div><div class="ing-info"><div class="ing-name">' + r.name + ' ' + r.weight + '</div></div><span class="ing-role">' + r.role + '</span></div>';
}).join('')
+ '</div>';
document.getElementById('dishSection').innerHTML =
'<div class="dish-sec-title">净菜包明细 · 食材 · 溯源</div>'
'<div class="dish-sec-title">' + dishTitle + '</div>'
+ '<div class="dish-card">'
+ '<div class="dish-head">'
+ '<div class="dish-icon">🍗</div>'
@@ -333,11 +380,7 @@
+ '</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>'
+ gongBaoIng
+ '</div>'
+ '<div class="dish-card">'
+ '<div class="dish-head">'
@@ -351,17 +394,51 @@
+ '</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>'
+ lowFatIng
+ '</div>'
+ '<div class="advice-card" style="margin:0;">'
+ '<div class="advice-title">🍳 烹制提示</div>'
+ '<div class="advice-text" style="color:#1677ff;">宫保鸡丁净菜包:热锅冷油下鸡丁滑炒至变色,加入配料包翻炒 2 分钟即可出锅;糙米饭需另行准备。</div>'
+ '</div>';
/* 订单进度时间线:按状态高亮对应节点 */
renderCleanTimeline(status);
}
/* 渲染净菜包订单进度时间线 */
function renderCleanTimeline(status) {
var states = ['submitted', 'prepared', 'delivering', 'shipping', 'arrived'];
var activeIdx;
if (status === 'delivering') {
activeIdx = 2; /* 高亮:待配送 */
} else if (status === 'shipped') {
activeIdx = 3; /* 高亮:配送中 */
} else { /* done */
activeIdx = 4; /* 全部完成:已送达 */
}
var nodes = [
{ title: '订单提交', time: '2026-04-28 14:23' },
{ title: '备货完成', time: '2026-04-28 15:00 截单' },
{ title: '待配送', time: '预计 2026-04-29 11:00 开始配送' },
{ title: '配送中', time: status === 'shipped' ? '骑手已取货,预计 30 分钟内送达' : '-' },
{ title: '已送达', time: status === 'done' ? '2026-04-29 12:08 送达' : '-' }
];
var html = '';
for (var i = 0; i < nodes.length; i++) {
var cls = '';
if (i < activeIdx) cls = 'done';
else if (i === activeIdx) cls = i === nodes.length - 1 ? 'done' : 'active';
else if (status === 'done' && i === activeIdx) cls = 'done';
html += '<div class="tl-item ' + cls + '">'
+ '<div class="tl-dot"></div>'
+ '<div class="tl-content">'
+ '<div class="tl-title">' + nodes[i].title + '</div>'
+ '<div class="tl-time">' + nodes[i].time + '</div>'
+ '</div>'
+ '</div>';
}
var timelineWrap = document.querySelector('#cleanExtra .timeline');
if (timelineWrap) timelineWrap.innerHTML = html;
}
</script>
</body>
@@ -70,7 +70,7 @@
<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">
<a class="order-card" href="me-order-detail.html?type=clean&status=delivering">
<div class="card-top">
<div class="shop-row"><span class="shop">🥬 阳光食堂 · 净菜包订单</span><span class="type-tag clean">净菜包</span></div>
<span class="status shipping">待配送</span>
@@ -87,7 +87,7 @@
<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">
<a class="order-card" href="me-order-detail.html?type=clean&status=done">
<div class="card-top">
<div class="shop-row"><span class="shop">🥬 阳光食堂 · 净菜包订单</span><span class="type-tag clean">净菜包</span></div>
<span class="status">已完成</span>