feat: 配送H5订单详情取货方式拆分(自助/到店取货) + 营养管理端餐线管理重构与餐盘柜餐盘编码

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
fengpu
2026-08-20 14:28:31 +08:00
co-authored by Claude Opus 4.7
parent d20f3913f6
commit c8322529cb
10 changed files with 1283 additions and 88 deletions
+1 -1
View File
@@ -510,7 +510,7 @@
<div class="dispatch-banner" onclick="location.href='02-dispatch-incoming.html'">
<div class="dispatch-banner__icon">📲</div>
<div class="dispatch-banner__text">
<div class="dispatch-banner__title">您有新的派单 · 倒计时 25s</div>
<div class="dispatch-banner__title">您有新的派单 · 已等待 5 分钟</div>
<div class="dispatch-banner__desc">味之都食堂 → 高新区科技路 12 号 · 1.8km</div>
</div>
<div class="dispatch-banner__arrow"></div>
@@ -0,0 +1,367 @@
<!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; }
:root {
--primary: #ff6d3a;
--primary-dark: #e85a28;
--primary-light: #fff0e8;
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-tertiary: #9ca3af;
--border: #e5e7eb;
--background: #f6f8fb;
--success: #10b981;
--info: #3b82f6;
--shadow-sm: 0 2px 8px rgba(15, 23, 42, 0.06);
}
body {
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
background: #2a2a2a;
color: var(--text-primary);
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif;
}
.phone-shell {
position: relative;
width: 375px;
height: 812px;
overflow: hidden;
display: flex;
flex-direction: column;
background: var(--background);
border-radius: 44px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3), inset 0 0 0 2px #e0e0e0;
}
/* 遮罩:模拟弹窗悬浮于订单详情页之上 */
.mask {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 10;
}
/* 底部弹层 */
.sheet {
position: absolute;
left: 0; right: 0; bottom: 0;
background: var(--background);
border-radius: 20px 20px 0 0;
padding: 12px 16px 40px;
z-index: 11;
display: flex;
flex-direction: column;
gap: 12px;
}
.sheet__grab {
width: 36px; height: 4px;
background: var(--border);
border-radius: 2px;
margin: 0 auto;
}
.sheet__title {
text-align: center;
font-size: 16px;
font-weight: 700;
}
.card {
background: white;
border-radius: 14px;
padding: 14px;
box-shadow: var(--shadow-sm);
}
.card__head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.card__title {
font-size: 14px;
font-weight: 700;
display: flex;
align-items: center;
gap: 6px;
}
.card__title::before {
content: '';
width: 4px; height: 14px;
background: var(--primary);
border-radius: 2px;
}
/* 货柜信息 */
.locker-row {
display: flex;
gap: 12px;
align-items: center;
}
.locker-icon {
width: 52px; height: 52px;
border-radius: 12px;
background: linear-gradient(135deg, #dbeafe, #eff6ff);
display: flex;
align-items: center;
justify-content: center;
font-size: 26px;
flex-shrink: 0;
}
.locker-info { flex: 1; }
.locker-name {
font-size: 14px;
font-weight: 700;
margin-bottom: 3px;
}
.locker-addr {
font-size: 12px;
color: var(--text-secondary);
line-height: 1.5;
}
.locker-cells {
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed var(--border);
display: flex;
gap: 8px;
}
.cell-tag {
flex: 1;
background: var(--primary-light);
border: 1px dashed var(--primary);
border-radius: 10px;
padding: 8px;
text-align: center;
}
.cell-tag__label {
font-size: 10px;
color: var(--text-secondary);
display: block;
margin-bottom: 2px;
}
.cell-tag__value {
font-size: 14px;
font-weight: 700;
color: var(--primary-dark);
}
/* 取货码 */
.pickup-code-card {
background: linear-gradient(135deg, var(--primary), var(--primary-dark));
border-radius: 14px;
padding: 16px;
color: white;
text-align: center;
}
.pickup-code-card__label {
font-size: 12px;
opacity: 0.9;
margin-bottom: 8px;
}
.pickup-code {
font-size: 40px;
font-weight: 800;
letter-spacing: 10px;
font-family: "SF Mono", Menlo, Consolas, monospace;
margin-bottom: 8px;
}
.pickup-code-card__tip {
font-size: 11px;
opacity: 0.85;
}
/* 拍照留证 */
.photo-grid {
display: flex;
gap: 10px;
}
.photo-thumb {
width: 96px; height: 96px;
border-radius: 10px;
background: linear-gradient(135deg, #fef3c7, #fed7aa);
display: flex;
align-items: center;
justify-content: center;
font-size: 34px;
position: relative;
flex-shrink: 0;
}
.photo-thumb__tag {
position: absolute;
bottom: 0; left: 0; right: 0;
background: rgba(0, 0, 0, 0.45);
color: white;
font-size: 10px;
padding: 3px 0;
border-radius: 0 0 10px 10px;
}
.photo-add {
width: 96px; height: 96px;
border-radius: 10px;
border: 1.5px dashed var(--text-tertiary);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
color: var(--text-secondary);
font-size: 11px;
cursor: pointer;
background: white;
flex-shrink: 0;
}
.photo-add__plus { font-size: 26px; color: var(--text-tertiary); line-height: 1; }
.photo-tip {
font-size: 11px;
color: var(--text-secondary);
margin-top: 8px;
}
/* 操作按钮 */
.btn {
height: 48px;
border: none;
border-radius: 12px;
font-size: 15px;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
width: 100%;
}
.btn--primary {
background: linear-gradient(135deg, var(--primary), var(--primary-dark));
color: white;
box-shadow: 0 6px 12px rgba(255, 109, 58, 0.25);
}
.btn--ghost {
background: transparent;
color: var(--text-secondary);
height: 36px;
font-size: 13px;
font-weight: 500;
}
.home-indicator {
position: absolute;
bottom: 8px; left: 50%;
transform: translateX(-50%);
width: 134px; height: 5px;
background: #1f2937;
border-radius: 3px;
z-index: 20;
}
.toast {
position: absolute;
top: 60px; left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
z-index: 100;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
white-space: nowrap;
}
.toast.show { opacity: 1; }
</style>
</head>
<body>
<div class="phone-shell">
<!-- 半透明遮罩,点击返回订单详情页 -->
<div class="mask" onclick="location.href='04-order-detail.html'"></div>
<!-- 交互说明:自助取货弹窗(底部弹层)。
场景:加工厂已将做好的订单餐品放入智能货柜,骑手到货柜处凭取货码开柜自取。
功能:1.查看货柜位置与格口编号 2.查看取货码 3.拍照对物品确认 -->
<div class="sheet">
<div class="sheet__grab"></div>
<div class="sheet__title">📦 自助取货</div>
<!-- 货柜详情 -->
<div class="card">
<div class="card__head">
<div class="card__title">货柜详情</div>
<span style="font-size:12px;color:var(--success);font-weight:600">● 餐品已入柜</span>
</div>
<div class="locker-row">
<div class="locker-icon">🗄️</div>
<div class="locker-info">
<div class="locker-name">味之都食堂·高新店 智能货柜</div>
<div class="locker-addr">高新区科技三路 8 号 · 店门东侧 5 米(临街)</div>
</div>
</div>
<div class="locker-cells">
<div class="cell-tag">
<span class="cell-tag__label">格口编号</span>
<span class="cell-tag__value">A-12</span>
</div>
<div class="cell-tag">
<span class="cell-tag__label">格口类型</span>
<span class="cell-tag__value">保温格口</span>
</div>
<div class="cell-tag">
<span class="cell-tag__label">入柜时间</span>
<span class="cell-tag__value">14:32</span>
</div>
</div>
</div>
<!-- 取货码 -->
<div class="pickup-code-card">
<div class="pickup-code-card__label">取货码(在货柜屏幕输入后开柜)</div>
<div class="pickup-code">862491</div>
<div class="pickup-code-card__tip">🧊 保温中 · 请在 15:20 前取货</div>
</div>
<!-- 拍照确认 -->
<div class="card">
<div class="card__head">
<div class="card__title">拍照确认物品</div>
<span style="font-size:12px;color:var(--text-secondary)">1/3 张</span>
</div>
<div class="photo-grid">
<!-- 交互说明:已拍摄照片缩略图示意 -->
<div class="photo-thumb">🍱<span class="photo-thumb__tag">14:35 已拍</span></div>
<!-- 交互说明:点击调起相机,开柜后对餐品拍照留证 -->
<div class="photo-add" onclick="toast('已调起相机')">
<span class="photo-add__plus"></span>
<span>拍摄餐品</span>
</div>
</div>
<div class="photo-tip">📸 请拍摄开柜后餐品状态,作为取货确认凭证</div>
</div>
<!-- 交互说明:点击「拍照确认取货」→ 提示取货成功并进入配送中 -->
<button class="btn btn--primary" onclick="confirmPickup()">📸 确认取货</button>
<button class="btn btn--ghost" onclick="location.href='04-order-detail.html'">返回订单详情</button>
</div>
<div class="home-indicator"></div>
<div class="toast" id="toast"></div>
</div>
<script>
function toast(msg) {
const t = document.getElementById('toast');
t.textContent = msg;
t.classList.add('show');
setTimeout(() => t.classList.remove('show'), 1800);
}
// 交互说明:确认取货后跳转配送中页面
function confirmPickup() {
toast('取货成功,开始配送');
setTimeout(() => location.href = '05-delivering.html', 1200);
}
</script>
</body>
</html>
@@ -0,0 +1,315 @@
<!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; }
:root {
--primary: #ff6d3a;
--primary-dark: #e85a28;
--primary-light: #fff0e8;
--text-primary: #1f2937;
--text-secondary: #6b7280;
--text-tertiary: #9ca3af;
--border: #e5e7eb;
--background: #f6f8fb;
--success: #10b981;
--shadow-sm: 0 2px 8px rgba(15, 23, 42, 0.06);
}
body {
min-height: 100vh;
display: flex;
align-items: flex-start;
justify-content: center;
background: #2a2a2a;
color: var(--text-primary);
font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", "Helvetica Neue", sans-serif;
}
.phone-shell {
position: relative;
width: 375px;
height: 812px;
overflow: hidden;
display: flex;
flex-direction: column;
background: var(--background);
border-radius: 44px;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3), inset 0 0 0 2px #e0e0e0;
}
/* 遮罩:模拟弹窗悬浮于订单详情页之上 */
.mask {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 10;
}
/* 底部弹层 */
.sheet {
position: absolute;
left: 0; right: 0; bottom: 0;
background: var(--background);
border-radius: 20px 20px 0 0;
padding: 12px 16px 40px;
z-index: 11;
display: flex;
flex-direction: column;
gap: 12px;
}
.sheet__grab {
width: 36px; height: 4px;
background: var(--border);
border-radius: 2px;
margin: 0 auto;
}
.sheet__title {
text-align: center;
font-size: 16px;
font-weight: 700;
}
.card {
background: white;
border-radius: 14px;
padding: 14px;
box-shadow: var(--shadow-sm);
}
.card__head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.card__title {
font-size: 14px;
font-weight: 700;
display: flex;
align-items: center;
gap: 6px;
}
.card__title::before {
content: '';
width: 4px; height: 14px;
background: var(--primary);
border-radius: 2px;
}
/* 商家信息 */
.store-row {
display: flex;
gap: 12px;
align-items: center;
}
.store-icon {
width: 52px; height: 52px;
border-radius: 12px;
background: linear-gradient(135deg, #fef3c7, #fde68a);
display: flex;
align-items: center;
justify-content: center;
font-size: 26px;
flex-shrink: 0;
}
.store-info { flex: 1; }
.store-name {
font-size: 14px;
font-weight: 700;
margin-bottom: 3px;
}
.store-addr {
font-size: 12px;
color: var(--text-secondary);
line-height: 1.5;
}
.store-actions {
margin-top: 10px;
padding-top: 10px;
border-top: 1px dashed var(--border);
display: flex;
gap: 8px;
}
.contact-tag {
background: var(--primary-light);
color: var(--primary-dark);
padding: 5px 12px;
border-radius: 12px;
font-size: 12px;
font-weight: 600;
text-decoration: none;
display: inline-flex;
align-items: center;
gap: 4px;
cursor: pointer;
}
/* 拍照留存 */
.photo-grid {
display: flex;
gap: 10px;
flex-wrap: wrap;
}
.photo-thumb {
width: 96px; height: 96px;
border-radius: 10px;
background: linear-gradient(135deg, #fef3c7, #fed7aa);
display: flex;
align-items: center;
justify-content: center;
font-size: 34px;
position: relative;
flex-shrink: 0;
}
.photo-thumb__tag {
position: absolute;
bottom: 0; left: 0; right: 0;
background: rgba(0, 0, 0, 0.45);
color: white;
font-size: 10px;
padding: 3px 0;
border-radius: 0 0 10px 10px;
}
.photo-add {
width: 96px; height: 96px;
border-radius: 10px;
border: 1.5px dashed var(--text-tertiary);
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 4px;
color: var(--text-secondary);
font-size: 11px;
cursor: pointer;
background: white;
flex-shrink: 0;
}
.photo-add__plus { font-size: 26px; color: var(--text-tertiary); line-height: 1; }
.photo-tip {
font-size: 11px;
color: var(--text-secondary);
margin-top: 8px;
line-height: 1.6;
}
/* 操作按钮 */
.btn {
height: 48px;
border: none;
border-radius: 12px;
font-size: 15px;
font-weight: 700;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
gap: 6px;
width: 100%;
}
.btn--primary {
background: linear-gradient(135deg, var(--primary), var(--primary-dark));
color: white;
box-shadow: 0 6px 12px rgba(255, 109, 58, 0.25);
}
.btn--ghost {
background: transparent;
color: var(--text-secondary);
height: 36px;
font-size: 13px;
font-weight: 500;
}
.home-indicator {
position: absolute;
bottom: 8px; left: 50%;
transform: translateX(-50%);
width: 134px; height: 5px;
background: #1f2937;
border-radius: 3px;
z-index: 20;
}
.toast {
position: absolute;
top: 60px; left: 50%;
transform: translateX(-50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 8px 16px;
border-radius: 20px;
font-size: 13px;
z-index: 100;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
white-space: nowrap;
}
.toast.show { opacity: 1; }
</style>
</head>
<body>
<div class="phone-shell">
<!-- 半透明遮罩,点击返回订单详情页 -->
<div class="mask" onclick="location.href='04-order-detail.html'"></div>
<!-- 交互说明:到店取货弹窗(底部弹层)。
场景:骑手到商家门店现场取货。
功能:1.查看商家位置/联系商家 2.拍照留存取货照片 3.开始配送 -->
<div class="sheet">
<div class="sheet__grab"></div>
<div class="sheet__title">🏪 到店取货</div>
<!-- 商家信息 -->
<div class="card">
<div class="card__head">
<div class="card__title">取货门店</div>
<span style="font-size:12px;color:var(--success);font-weight:600">● 餐品已出餐</span>
</div>
<div class="store-row">
<div class="store-icon">🏢</div>
<div class="store-info">
<div class="store-name">味之都食堂·高新店</div>
<div class="store-addr">高新区科技三路 8 号 · 联系人:王经理</div>
</div>
</div>
<div class="store-actions">
<a href="javascript:void(0)" class="contact-tag" onclick="toast('正在呼叫商家')">📞 呼叫商家</a>
<a href="javascript:void(0)" class="contact-tag" onclick="toast('已打开导航')">📍 导航到店</a>
</div>
</div>
<!-- 拍照留存 -->
<div class="card">
<div class="card__head">
<div class="card__title">取货拍照留存</div>
<span style="font-size:12px;color:var(--text-secondary)">1/3 张</span>
</div>
<div class="photo-grid">
<!-- 交互说明:已拍摄照片缩略图示意 -->
<div class="photo-thumb">🍱<span class="photo-thumb__tag">14:36 已拍</span></div>
<!-- 交互说明:点击调起相机,对取货餐品/交接现场拍照留证 -->
<div class="photo-add" onclick="toast('已调起相机')">
<span class="photo-add__plus"></span>
<span>拍摄取货现场</span>
</div>
</div>
<div class="photo-tip">📸 请拍摄餐品包装与交接现场,作为取货留存凭证;拍摄完成后即可开始配送</div>
</div>
<!-- 交互说明:点击「拍照并开始配送」→ 跳转配送中页面 -->
<button class="btn btn--primary" onclick="location.href='05-delivering.html'">📸 开始配送</button>
<button class="btn btn--ghost" onclick="location.href='04-order-detail.html'">返回订单详情</button>
</div>
<div class="home-indicator"></div>
<div class="toast" id="toast"></div>
</div>
<script>
function toast(msg) {
const t = document.getElementById('toast');
t.textContent = msg;
t.classList.add('show');
setTimeout(() => t.classList.remove('show'), 1800);
}
</script>
</body>
</html>
@@ -359,6 +359,17 @@
color: white;
box-shadow: 0 6px 12px rgba(255, 109, 58, 0.25);
}
.btn--outline {
background: white;
color: var(--primary);
border: 1.5px solid var(--primary);
}
.btn__sub {
display: block;
font-size: 10px;
font-weight: 400;
opacity: 0.85;
}
.tag-list {
display: flex;
@@ -572,6 +583,10 @@
<span class="info-label">收货方式</span>
<span class="info-value" style="color:var(--primary)">🔢 验证码收货</span>
</div>
<div class="info-row">
<span class="info-label">取货方式</span>
<span class="info-value" style="color:var(--info)">📦 自助取货 / 🏪 到店取货</span>
</div>
</div>
</div>
@@ -587,8 +602,12 @@
</div>
<!-- 交互说明:底部双按钮,取货方式二选一。
自助取货 = 加工厂已将餐品放入智能货柜,骑手凭验证码开柜自取;
到店取货 = 骑手到商家门店现场取货 -->
<div class="action-bar">
<button class="btn btn--primary" onclick="location.href='05-delivering.html'">🚀 到店报到</button>
<button class="btn btn--primary" onclick="location.href='04-order-detail-selfpickup-dialog.html'">📦 自助取货</button>
<button class="btn btn--outline" onclick="location.href='04-order-detail-storepickup-dialog.html'">🏪 到店取货</button>
</div>
<div class="home-indicator"></div>
@@ -1,5 +1,30 @@
# 营养管理餐品配送 H5 模块变更日志
## 2026-08-19 · 订单详情取货方式拆分(自助取货 / 到店取货)
### 新增
- **`04-order-detail-selfpickup-dialog.html` 自助取货弹窗**:加工厂将做好的餐品放入智能货柜,骑手凭取货码开柜自取
- 货柜详情:货柜名称/位置/格口编号(A-12 保温格口)/入柜时间
- 取货码展示:大字号验证码(862491),提示在货柜屏幕输入开柜,含取货时限
- 拍照确认物品:已拍缩略图 + 调起相机卡槽
- 「拍照确认取货」→ 提示取货成功并跳转配送中
- **`04-order-detail-storepickup-dialog.html` 到店取货弹窗**:骑手到商家门店现场取货
- 取货门店信息:商家名/地址/呼叫商家/导航到店
- 取货拍照留存:餐品包装与交接现场拍照
- 「拍照并开始配送」→ 跳转配送中
### 优化
- **`04-order-detail.html` 底部按钮拆分**:原「到店报到」单按钮拆为「📦 自助取货(智能货柜·凭码开柜)」+「🏪 到店取货(现场拍照·开始配送)」双按钮
- **`04-order-detail.html` 订单信息新增「取货方式」行**
- **`01-home.html` 派单横幅文案调整**:「倒计时 25s」→「已等待 5 分钟」
### 业务约定更新
- 取货方式二选一:自助取货(智能货柜验证码开柜) / 到店取货(门店现场交接)
- 自助取货流程:加工厂入柜 → 骑手查看货柜位置/格口 → 凭取货码开柜 → 拍照确认 → 开始配送
- 到店取货流程:骑手到店 → 拍照留存取货凭证 → 开始配送
---
## 2026-08-14 · 派单/配送流程降噪与信息补全
### 优化