dm-design/专员APP/工作台/专员端-订单详情演示.html

708 lines
22 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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 {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
background-color: #e5e5e5;
}
.navbar {
background: linear-gradient(135deg, #053C23 0%, #0a5a35 100%);
color: white;
padding: 12px 16px;
display: flex;
align-items: center;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}
.back-btn {
font-size: 24px;
cursor: pointer;
margin-right: 12px;
}
.navbar-title {
font-size: 18px;
font-weight: 500;
}
.info-bar {
background: #e5e5e5;
padding: 0 20px;
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
color: #333;
font-size: 14px;
}
.info-time {
font-size: 12px;
color: #808080;
margin-left: 8px;
}
.countdown {
color: #ff4444;
display: flex;
align-items: center;
gap: 4px;
}
.divider {
background: #e5e5e5;
height: 10px;
width: 100%;
}
.order-note {
background: white;
padding: 30px 20px;
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 10px solid #e5e5e5;
}
.note-label {
color: #808080;
font-size: 18px;
margin-right: 40px;
flex-shrink: 0;
}
.note-content {
flex: 1;
color: #000;
font-size: 18px;
}
.shop-list {
padding: 0 20px;
background: white;
}
.shop-item {
padding: 20px 0;
border-bottom: 1px solid #e5e5e5;
}
.shop-item:last-child {
border-bottom: none;
}
.shop-header {
display: flex;
align-items: center;
flex-wrap: wrap;
padding-bottom: 8px;
font-size: 18px;
font-weight: 400;
color: #333;
}
.shop-status {
display: flex;
align-items: center;
justify-content: space-between;
height: 40px;
font-size: 16px;
}
.status-item {
display: flex;
align-items: center;
}
.status-icon {
width: 21px;
height: 21px;
margin-left: 10px;
}
.btn-pickup {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 8px 20px;
border-radius: 20px;
font-size: 14px;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 2px 8px rgba(102, 126, 234, 0.3);
}
.btn-pickup:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(102, 126, 234, 0.4);
}
.completed {
color: #4CAF50;
}
.footer {
position: fixed;
bottom: 0;
left: 0;
right: 0;
background: white;
padding: 12px 20px;
border-top: 1px solid #e5e5e5;
display: flex;
gap: 12px;
}
.btn-secondary {
flex: 1;
background: white;
border: 1px solid #053C23;
color: #053C23;
padding: 10px;
border-radius: 20px;
font-size: 15px;
cursor: pointer;
transition: all 0.3s;
}
.btn-secondary:hover {
background: #f5f5f5;
}
.btn-primary {
flex: 1;
background: linear-gradient(135deg, #053C23 0%, #0a5a35 100%);
color: white;
border: none;
padding: 10px;
border-radius: 20px;
font-size: 15px;
cursor: pointer;
transition: all 0.3s;
box-shadow: 0 2px 8px rgba(5, 60, 35, 0.3);
}
.btn-primary:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(5, 60, 35, 0.4);
}
/* 弹窗样式 */
.modal {
display: none;
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
z-index: 1000;
animation: fadeIn 0.3s;
align-items: center;
justify-content: center;
}
.modal.show {
display: flex;
}
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideUp {
from {
opacity: 0;
transform: translateY(20px) scale(0.95);
}
to {
opacity: 1;
transform: translateY(0) scale(1);
}
}
/* 取货弹窗 */
.pickup-popup {
background: white;
border-radius: 12px;
width: 90%;
max-width: 400px;
max-height: 80vh;
display: flex;
flex-direction: column;
z-index: 1001;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
opacity: 0;
transition: all 0.3s;
}
.pickup-popup.show {
animation: slideUp 0.3s forwards;
}
.popup-header {
background: #e5e5e5;
padding: 12px 16px;
text-align: center;
font-size: 16px;
font-weight: 500;
border-radius: 12px 12px 0 0;
position: relative;
}
.close-btn {
position: absolute;
right: 12px;
top: 50%;
transform: translateY(-50%);
font-size: 24px;
color: #666;
cursor: pointer;
line-height: 1;
padding: 4px;
}
.close-btn:hover {
color: #333;
}
.popup-body {
flex: 1;
overflow-y: auto;
padding: 10px;
}
.product-item {
display: flex;
padding: 12px 0;
border-bottom: 1px solid #e5e5e5;
}
.product-item:last-child {
border-bottom: none;
}
.product-image {
width: 46px;
height: 46px;
border-radius: 6px;
border: 1px solid #e5e5e5;
margin-right: 10px;
object-fit: cover;
cursor: pointer;
}
.product-info {
flex: 1;
display: flex;
flex-direction: column;
justify-content: space-between;
color: #808080;
font-size: 13px;
}
.product-name {
color: #333;
margin-bottom: 4px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.product-spec {
display: flex;
justify-content: space-between;
}
.popup-footer {
border-top: 1px solid #e5e5e5;
padding: 12px 16px;
display: flex;
justify-content: flex-end;
border-radius: 0 0 12px 12px;
}
.toast {
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background: rgba(0, 0, 0, 0.8);
color: white;
padding: 12px 24px;
border-radius: 8px;
z-index: 2000;
display: none;
animation: fadeIn 0.3s;
}
.toast.show {
display: block;
}
.content-wrapper {
padding-bottom: 60px;
}
</style>
</head>
<body>
<div class="navbar">
<span class="back-btn" onclick="goBack()"></span>
<span class="navbar-title">订单详情</span>
</div>
<div class="content-wrapper">
<div class="info-bar">
<div>
<span>单号 #<span id="daySn"></span></span>
<span class="info-time" id="payTime"></span>
</div>
<div class="countdown">
<span>剩余</span>
<span id="countdown">--:--</span>
</div>
</div>
<div class="info-bar">
<div>订单编号 <span id="unitOrderNo"></span></div>
</div>
<div class="info-bar">
<span style="color: #808080;">摊位数<span id="shopCount"></span></span>
<span style="color: #808080;">商品数<span id="productCount"></span></span>
<span></span>
</div>
<div class="order-note">
<div class="note-label">订单备注</div>
<div class="note-content" id="orderRemark"></div>
</div>
<div class="shop-list" id="shopList">
<!-- 店铺列表将通过JavaScript动态生成 -->
</div>
</div>
<!-- 取货弹窗 -->
<div id="pickupModal" class="modal">
<div class="pickup-popup" id="pickupPopup">
<div class="popup-header">
核对货品
<span class="close-btn" onclick="closePickupPopup()">×</span>
</div>
<div class="popup-body" id="productList">
<!-- 商品列表将通过JavaScript动态生成 -->
</div>
<div class="popup-footer">
<button class="btn-primary" onclick="handlePickupDone()">取货完成</button>
</div>
</div>
</div>
<!-- Toast提示 -->
<div id="toast" class="toast"></div>
<script>
// 从sessionStorage获取订单信息
let orderInfo = null;
try {
orderInfo = JSON.parse(sessionStorage.getItem('currentOrder'));
} catch (e) {
// 如果没有订单信息,使用模拟数据
orderInfo = {
unitOrderNo: 'U2024101201',
daySn: '20241012001',
payTime: '2024-10-12 09:30:15',
preparedCount: 3,
totalCount: 4,
distance: 2.5,
expectDeliveryTime: 15,
deliveryType: 1,
orderCategory: 1,
orderStatus: 2 // 默认待取货状态
};
}
// 判断是否为待配送订单
const isDeliveryPending = orderInfo.orderStatus === 3;
// 模拟订单详细数据
const mockOrderDetail = {
shopCount: 4,
productCount: 12,
remark: '请尽快配送,客户急需',
shopOrderDTOList: [
{
shopOrderNo: 'S2024101201',
daySn: '1', // 店铺订单流水号
shopName: '张大妈生鲜店',
detailAddress: 'A区23号',
pickStatus: 0, // 0:未取货 1:已取货 2:待备货
products: [
{
productImg: 'https://via.placeholder.com/46/4CAF50/FFFFFF?text=蔬菜',
productName: '新鲜蔬菜 - 有机西红柿',
productSpecName: '500g/份',
productCount: 2
},
{
productImg: 'https://via.placeholder.com/46/2196F3/FFFFFF?text=水果',
productName: '优质水果 - 进口苹果',
productSpecName: '1kg/盒',
productCount: 1
}
]
},
{
shopOrderNo: 'S2024101202',
daySn: '2',
shopName: '李阿姨水果摊',
detailAddress: 'B区05号',
pickStatus: 0,
products: [
{
productImg: 'https://via.placeholder.com/46/FF9800/FFFFFF?text=水果',
productName: '新鲜香蕉',
productSpecName: '500g/把',
productCount: 3
}
]
},
{
shopOrderNo: 'S2024101203',
daySn: '3',
shopName: '王师傅肉类专营',
detailAddress: 'C区12号',
pickStatus: 1, // 已取货
products: [
{
productImg: 'https://via.placeholder.com/46/E91E63/FFFFFF?text=肉类',
productName: '精品肉类 - 鲜猪肉',
productSpecName: '250g/份',
productCount: 2
}
]
},
{
shopOrderNo: 'S2024101204',
daySn: '4',
shopName: '海鲜大咖',
detailAddress: 'D区08号',
pickStatus: 2, // 待备货
products: [
{
productImg: 'https://via.placeholder.com/46/9C27B0/FFFFFF?text=海鲜',
productName: '海鲜水产 - 活虾',
productSpecName: '300g/份',
productCount: 4
}
]
}
]
};
let currentShop = null;
// 初始化页面
function initPage() {
// 显示订单基本信息
document.getElementById('daySn').textContent = orderInfo.daySn;
document.getElementById('payTime').textContent = orderInfo.payTime;
document.getElementById('unitOrderNo').textContent = orderInfo.unitOrderNo;
document.getElementById('shopCount').textContent = mockOrderDetail.shopCount;
document.getElementById('productCount').textContent = mockOrderDetail.productCount;
document.getElementById('orderRemark').textContent = mockOrderDetail.remark;
// 启动倒计时
startCountdown();
// 渲染店铺列表
renderShopList();
}
// 倒计时
function startCountdown() {
// 模拟30分钟倒计时
let seconds = 30 * 60;
function update() {
const minutes = Math.floor(seconds / 60);
const secs = seconds % 60;
document.getElementById('countdown').textContent =
`${String(minutes).padStart(2, '0')}:${String(secs).padStart(2, '0')}`;
if (seconds > 0) {
seconds--;
setTimeout(update, 1000);
}
}
update();
}
// 渲染店铺列表
function renderShopList() {
const shopList = document.getElementById('shopList');
shopList.innerHTML = mockOrderDetail.shopOrderDTOList.map(shop => {
// 如果是待配送订单,所有店铺订单状态都显示为"取货完成"
const displayPickStatus = isDeliveryPending ? 1 : shop.pickStatus;
return `
<div class="shop-item">
<div class="shop-header">
<span>${shop.shopName}(${shop.detailAddress})</span>
</div>
<div style="color: #808080; font-size: 14px; padding: 4px 0 8px 0;">
店铺订单流水号 ${shop.daySn}
</div>
<div class="shop-status">
<div class="status-item ${displayPickStatus === 1 ? 'completed' : displayPickStatus === 2 ? '' : ''}">
<span>${displayPickStatus === 2 ? '待备货' : '备货完成'}</span>
${displayPickStatus !== 2 ? `
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234CAF50'%3E%3Cpath d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z'/%3E%3C/svg%3E" class="status-icon" alt="完成" />
` : ''}
</div>
${!isDeliveryPending && displayPickStatus === 0 ? `
<button class="btn-pickup" onclick="openPickupPopup('${shop.shopOrderNo}')">取货</button>
` : displayPickStatus === 1 ? `
<div class="status-item completed">
<span>取货完成</span>
<img src="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%234CAF50'%3E%3Cpath d='M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z'/%3E%3C/svg%3E" class="status-icon" alt="完成" />
</div>
` : ''}
</div>
</div>
`;
}).join('');
}
// 打开取货弹窗
function openPickupPopup(shopOrderNo) {
const shop = mockOrderDetail.shopOrderDTOList.find(s => s.shopOrderNo === shopOrderNo);
if (!shop) return;
currentShop = shop;
// 渲染商品列表
const productList = document.getElementById('productList');
productList.innerHTML = shop.products.map((product, index) => `
<div class="product-item">
<img src="${product.productImg}" class="product-image" alt="${product.productName}"
onclick="previewImage('${product.productImg}')" />
<div class="product-info">
<div class="product-name">${product.productName}</div>
<div class="product-spec">
<span>${product.productSpecName}</span>
<span>x${product.productCount}</span>
</div>
</div>
</div>
`).join('');
// 显示弹窗
const modal = document.getElementById('pickupModal');
const popup = document.getElementById('pickupPopup');
modal.classList.add('show');
// 延迟一帧后添加show类确保动画能够播放
requestAnimationFrame(() => {
popup.classList.add('show');
});
}
// 关闭取货弹窗
function closePickupPopup() {
const modal = document.getElementById('pickupModal');
const popup = document.getElementById('pickupPopup');
popup.classList.remove('show');
// 等待动画结束后移除modal
setTimeout(() => {
modal.classList.remove('show');
}, 300);
}
// 处理取货完成
function handlePickupDone() {
// 显示操作选择
const actions = ['补差价', '确认'];
const actionIndex = Math.random() > 0.5 ? 1 : prompt('请选择操作:\n0 - 补差价\n1 - 确认', '1');
if (actionIndex === null) {
return;
}
if (actionIndex === '0') {
// 补差价
closePickupPopup();
showToast('正在跳转到补差价页面...');
setTimeout(() => {
window.open('退差价演示页面.html', '_blank');
}, 500);
} else {
// 确认取货
const needPhoto = confirm('是否拍照留痕?');
if (needPhoto) {
showToast('正在打开相机...');
setTimeout(() => {
completePickup();
}, 1000);
} else {
completePickup();
}
}
}
// 完成取货
function completePickup() {
if (currentShop) {
currentShop.pickStatus = 1;
showToast('取货成功');
closePickupPopup();
renderShopList();
}
}
// 图片预览
function previewImage(url) {
showToast('预览图片: ' + url);
}
// 显示Toast
function showToast(message) {
const toast = document.getElementById('toast');
toast.textContent = message;
toast.classList.add('show');
setTimeout(() => {
toast.classList.remove('show');
}, 2000);
}
// 返回
function goBack() {
window.location.href = '专员端-订单列表演示.html';
}
// 点击模态框背景关闭
document.getElementById('pickupModal').addEventListener('click', function(e) {
if (e.target === this) {
closePickupPopup();
}
});
// 初始化页面
initPage();
</script>
</body>
</html>