You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1113 lines
24 KiB
1113 lines
24 KiB
<template>
|
|
<view class="order-detail-container">
|
|
<!-- 订单状态头部 -->
|
|
<view class="status-header">
|
|
<view class="status-badge" :class="[getStatusClass(orderDetail.status)]">
|
|
{{ getStatusText(orderDetail.status) }}
|
|
</view>
|
|
<view class="order-title">有感商品订单详情</view>
|
|
</view>
|
|
|
|
<!-- 收货地址 -->
|
|
<view class="address-section" v-if="orderDetail.receiverArea">
|
|
<view class="section-title">收货地址</view>
|
|
<view class="address-card">
|
|
<view class="address-text">
|
|
{{ orderDetail.receiverProvince }}{{ orderDetail.receiverCity
|
|
}}{{ orderDetail.receiverArea }}{{ orderDetail.receiverAddress }}
|
|
</view>
|
|
<view class="contact-info">
|
|
<text class="contact-name">{{ orderDetail.receiverName }}</text>
|
|
<text class="contact-phone">{{ orderDetail.receiverPhone }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 商品列表 -->
|
|
<view class="goods-section">
|
|
<view class="section-title">商品信息</view>
|
|
<view class="goods-list">
|
|
<view class="goods-item" v-for="goods in orderDetail.orderItems">
|
|
<view class="goods-image-container">
|
|
<image
|
|
mode="aspectFill"
|
|
:src="goods.specImage"
|
|
class="goods-image"
|
|
/>
|
|
</view>
|
|
<view class="goods-content">
|
|
<view class="goods-info">
|
|
<view class="goods-name">{{ goods.goodsName || "-" }}</view>
|
|
<view class="goods-specs">
|
|
<view class="spec-tag">
|
|
{{ goods.specValueOne }}-{{ goods.specValueTwo }}
|
|
</view>
|
|
</view>
|
|
<view class="goods-quantity-price">
|
|
<text class="goods-quantity"
|
|
>数量:{{ goods.quantity || 1 }}</text
|
|
>
|
|
<text class="goods-price">¥{{ goods.price }}</text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 金额汇总 -->
|
|
<view class="amount-summary">
|
|
<view class="summary-row">
|
|
<text class="summary-label">运费</text>
|
|
<text class="summary-value"
|
|
>¥{{ orderDetail.shippingFee || "0.00" }}</text
|
|
>
|
|
</view>
|
|
<view class="summary-row">
|
|
<text class="summary-label">总金额</text>
|
|
<text class="summary-value"
|
|
>¥{{ orderDetail.totalAmount || "0.00" }}</text
|
|
>
|
|
</view>
|
|
<view class="summary-row">
|
|
<text class="summary-label">积分抵扣</text>
|
|
<text class="summary-value"
|
|
>-¥{{ orderDetail.pointsDeductAmount || "0.00" }}</text
|
|
>
|
|
</view>
|
|
<view class="summary-row total-row">
|
|
<text class="summary-label">应付金额</text>
|
|
<text class="summary-value total-amount"
|
|
>¥{{ orderDetail.payAmount || "0.00" }}</text
|
|
>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 订单信息 -->
|
|
<view class="order-info-section">
|
|
<view class="section-title">订单信息</view>
|
|
<view class="info-row">
|
|
<text class="info-label">订单编号</text>
|
|
<text class="info-value" @longpress="copyOrderNo">{{
|
|
orderDetail.orderNo
|
|
}}</text>
|
|
</view>
|
|
<view class="info-row">
|
|
<text class="info-label">下单时间</text>
|
|
<text class="info-value">{{ orderDetail.createTime }}</text>
|
|
</view>
|
|
<view class="info-row" v-if="orderDetail.payTime">
|
|
<text class="info-label">支付时间</text>
|
|
<text class="info-value">{{ orderDetail.payTime }}</text>
|
|
</view>
|
|
<view class="info-row" v-if="orderDetail.shippingTime">
|
|
<text class="info-label">发货时间</text>
|
|
<text class="info-value">{{ orderDetail.shippingTime }}</text>
|
|
</view>
|
|
<view class="info-row" v-if="orderDetail.completeTime">
|
|
<text class="info-label">完成时间</text>
|
|
<text class="info-value">{{ orderDetail.completeTime }}</text>
|
|
</view>
|
|
<!-- <view class="info-row">
|
|
<text class="info-label">支付方式</text>
|
|
<text class="info-value">{{
|
|
orderDetail.payMethod || "在线支付"
|
|
}}</text>
|
|
</view> -->
|
|
<view class="info-row" v-if="orderDetail.remark">
|
|
<text class="info-label">订单备注</text>
|
|
<text class="info-value">{{ orderDetail.remark }}</text>
|
|
</view>
|
|
<view
|
|
class="info-row"
|
|
v-if="orderDetail.delivery && orderDetail.delivery.expressName"
|
|
>
|
|
<text class="info-label">快递公司</text>
|
|
<text class="info-value">{{ orderDetail.delivery.expressName }}</text>
|
|
</view>
|
|
<view
|
|
class="info-row"
|
|
v-if="orderDetail.delivery && orderDetail.delivery.expressCode"
|
|
>
|
|
<text class="info-label">快递单号</text>
|
|
<text class="info-value" @longpress="copyExpressCode">{{
|
|
orderDetail.delivery.expressCode
|
|
}}</text>
|
|
</view>
|
|
<view
|
|
class="info-row"
|
|
v-if="orderDetail.delivery && orderDetail.delivery.expressTime"
|
|
>
|
|
<text class="info-label">发货时间</text>
|
|
<text class="info-value">{{ orderDetail.delivery.expressTime }}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 底部按钮占位div -->
|
|
<view class="bottom-placeholder"></view>
|
|
|
|
<!-- 底部操作 -->
|
|
<view class="bottom-actions" v-if="showBottomActions">
|
|
<button
|
|
class="action-btn-bottom"
|
|
@click="handleOrderAction('pay')"
|
|
v-if="orderDetail.status === 0"
|
|
>
|
|
去支付
|
|
</button>
|
|
<button
|
|
class="action-btn-bottom cancel-btn"
|
|
@click="handleOrderAction('cancel')"
|
|
v-if="orderDetail.status === 0"
|
|
>
|
|
取消订单
|
|
</button>
|
|
<!-- <button
|
|
class="action-btn-bottom"
|
|
@click="handleOrderAction('logistics')"
|
|
v-if="[2, 3].includes(orderDetail.status)"
|
|
>
|
|
查看物流
|
|
</button> -->
|
|
<button
|
|
class="action-btn-bottom confirm-btn"
|
|
@click="handleOrderAction('confirm')"
|
|
v-if="orderDetail.status === 2"
|
|
>
|
|
确认收货
|
|
</button>
|
|
<button
|
|
class="action-btn-bottom after-sale-btn"
|
|
@click="handleOrderAction('aftersale')"
|
|
v-if="orderDetail.status === 3"
|
|
>
|
|
申请售后
|
|
</button>
|
|
</view>
|
|
|
|
<!-- 物流详情弹窗 -->
|
|
<view
|
|
class="logistics-popup-mask"
|
|
v-if="showLogisticsPopup"
|
|
@click="closeLogisticsPopup"
|
|
>
|
|
<view class="logistics-popup" @click.stop>
|
|
<view class="popup-header">
|
|
<text class="popup-title">物流详情</text>
|
|
<text class="popup-close" @click="closeLogisticsPopup">×</text>
|
|
</view>
|
|
<view class="popup-content">
|
|
<!-- 物流状态 -->
|
|
<view class="logistics-detail-section">
|
|
<view class="detail-title">物流状态</view>
|
|
<view class="logistics-status-info">
|
|
{{ getLogisticsStatusText(orderDetail.logisticsStatus) }}
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 快递信息 -->
|
|
<view class="logistics-detail-section">
|
|
<view class="detail-title">快递信息</view>
|
|
<view class="info-item">
|
|
<text class="info-label">快递公司:</text>
|
|
<text class="info-value">{{
|
|
orderDetail.expressCompany || "--"
|
|
}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="info-label">快递单号:</text>
|
|
<text class="info-value" @longpress="copyExpressNo">{{
|
|
orderDetail.expressNo || "--"
|
|
}}</text>
|
|
</view>
|
|
<view class="info-item">
|
|
<text class="info-label">发货时间:</text>
|
|
<text class="info-value">{{
|
|
orderDetail.shippingTime || "--"
|
|
}}</text>
|
|
</view>
|
|
</view>
|
|
|
|
<!-- 物流轨迹 -->
|
|
<view
|
|
class="logistics-detail-section"
|
|
v-if="logisticsTrace && logisticsTrace.length > 0"
|
|
>
|
|
<view class="detail-title">物流轨迹</view>
|
|
<view class="trace-list">
|
|
<view
|
|
class="trace-item"
|
|
v-for="(trace, index) in logisticsTrace"
|
|
:key="index"
|
|
:class="{ 'is-current': index === 0 }"
|
|
>
|
|
<view class="trace-time">{{ trace.time }}</view>
|
|
<view class="trace-status">{{ trace.status }}</view>
|
|
<view class="trace-location" v-if="trace.location">{{
|
|
trace.location
|
|
}}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
export default {
|
|
data() {
|
|
return {
|
|
orderId: "",
|
|
showLogisticsPopup: false,
|
|
logisticsTrace: [], // 物流轨迹
|
|
orderDetail: {
|
|
orderGoods: [],
|
|
addressInfo: null,
|
|
},
|
|
};
|
|
},
|
|
computed: {
|
|
// 是否显示底部操作按钮
|
|
showBottomActions() {
|
|
return [0, 2, 3].includes(this.orderDetail.status);
|
|
},
|
|
},
|
|
onLoad(options) {
|
|
if (options.id) {
|
|
this.orderId = options.id;
|
|
}
|
|
},
|
|
onShow() {
|
|
this.loadOrderDetail();
|
|
},
|
|
methods: {
|
|
showImgJdsz(img) {
|
|
if (!img) return "/static/images/default-goods.png";
|
|
if (img.indexOf("https://") != -1 || img.indexOf("http://") != -1) {
|
|
return img;
|
|
} else {
|
|
return this.JDSU_IMG_URL + img;
|
|
}
|
|
},
|
|
|
|
// 加载订单详情
|
|
async loadOrderDetail() {
|
|
try {
|
|
this.Post(
|
|
{ parentNo: this.orderId },
|
|
`/framework/ygOrder/parent/getByParentNo`,
|
|
"DES"
|
|
).then((res) => {
|
|
if (res.code == 200) {
|
|
let orderItems = [];
|
|
res.data.orderNo = res.data.parentOrderNo;
|
|
res.data.orders.forEach((item) => {
|
|
item.orderItems.forEach((_item) => {
|
|
orderItems.push(_item);
|
|
});
|
|
});
|
|
this.orderDetail = res.data;
|
|
this.orderDetail.orderItems = orderItems;
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg,
|
|
icon: "none",
|
|
});
|
|
}
|
|
});
|
|
} catch (error) {
|
|
console.error("加载订单详情失败:", error);
|
|
uni.showToast({
|
|
title: "加载失败",
|
|
icon: "none",
|
|
});
|
|
} finally {
|
|
uni.hideLoading();
|
|
}
|
|
},
|
|
|
|
// 获取订单状态文本
|
|
getStatusText(status) {
|
|
const statusMap = {
|
|
"-1": "已取消",
|
|
0: "待支付",
|
|
1: "已支付",
|
|
2: "已发货",
|
|
3: "已完成",
|
|
};
|
|
return statusMap[status] || "未知";
|
|
},
|
|
|
|
// 获取状态样式类
|
|
getStatusClass(status) {
|
|
const classMap = {
|
|
"-1": "status-cancelled",
|
|
0: "status-pending",
|
|
1: "status-paid",
|
|
2: "status-shipping",
|
|
3: "status-completed",
|
|
};
|
|
return classMap[status] || "status-default";
|
|
},
|
|
|
|
// 获取物流状态文本
|
|
getLogisticsStatusText(status) {
|
|
const statusMap = {
|
|
0: "待发货",
|
|
1: "已发货",
|
|
2: "运输中",
|
|
3: "派送中",
|
|
4: "已签收",
|
|
5: "异常",
|
|
};
|
|
return statusMap[status] || "待发货";
|
|
},
|
|
|
|
// 处理订单操作
|
|
handleOrderAction(action) {
|
|
switch (action) {
|
|
case "pay":
|
|
this.goToPay();
|
|
break;
|
|
case "logistics":
|
|
this.showLogisticsDetail();
|
|
break;
|
|
case "confirm":
|
|
this.confirmReceipt();
|
|
break;
|
|
case "contact":
|
|
this.contactSupplier();
|
|
break;
|
|
case "aftersale":
|
|
this.applyAfterSale();
|
|
break;
|
|
case "cancel":
|
|
this.cancelOrder();
|
|
break;
|
|
}
|
|
},
|
|
|
|
// 取消订单
|
|
cancelOrder() {
|
|
uni.showModal({
|
|
title: "取消订单",
|
|
content: "确定要取消该订单吗?",
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
this.cancelOrderApi();
|
|
}
|
|
},
|
|
});
|
|
},
|
|
|
|
// 取消订单API
|
|
cancelOrderApi() {
|
|
uni.showLoading({
|
|
title: "取消中...",
|
|
});
|
|
|
|
this.Post(
|
|
{ parentOrderNo: this.orderDetail.orderNo },
|
|
`/framework/ygOrder/cancel`,
|
|
"DES"
|
|
).then((res) => {
|
|
uni.hideLoading();
|
|
if (res.code == 200) {
|
|
uni.showToast({
|
|
title: "订单已取消",
|
|
icon: "success",
|
|
});
|
|
setTimeout(() => {
|
|
this.loadOrderDetail();
|
|
}, 800);
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || "取消订单失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
});
|
|
},
|
|
|
|
// 去支付
|
|
goToPay() {
|
|
let order = this.orderDetail;
|
|
this.Post(
|
|
{
|
|
method: "POST",
|
|
orderNo: order.orderNo,
|
|
fromType: 2,
|
|
payAmount: order.payAmount,
|
|
},
|
|
"/framework/wxPay/submitShopPurOrder",
|
|
"DES"
|
|
).then((res) => {
|
|
uni.requestPayment({
|
|
nonceStr: res.data.wxInfo.nonceStr,
|
|
package: res.data.wxInfo.package,
|
|
paySign: res.data.wxInfo.paySign,
|
|
signType: res.data.wxInfo.signType,
|
|
timeStamp: res.data.wxInfo.timeStamp,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: "支付成功",
|
|
icon: "success",
|
|
});
|
|
setTimeout(() => {
|
|
uni.navigateBack({
|
|
delta: 1,
|
|
});
|
|
}, 800);
|
|
},
|
|
fail() {
|
|
// uni.navigateTo({
|
|
// url: '/subPackages/order/trades'
|
|
// })
|
|
},
|
|
});
|
|
});
|
|
},
|
|
|
|
// 显示物流详情
|
|
showLogisticsDetail() {
|
|
if (this.orderDetail.expressNo) {
|
|
this.loadLogisticsTrace();
|
|
this.showLogisticsPopup = true;
|
|
} else {
|
|
uni.showToast({
|
|
title: "暂无物流信息",
|
|
icon: "none",
|
|
});
|
|
}
|
|
},
|
|
|
|
// 加载物流轨迹
|
|
loadLogisticsTrace() {
|
|
this.Post(
|
|
{
|
|
orderId: this.orderId,
|
|
expressNo: this.orderDetail.expressNo,
|
|
},
|
|
"/framework/haveFeeling/order/logistics/trace",
|
|
"DES"
|
|
).then((res) => {
|
|
if (res.code == 200) {
|
|
this.logisticsTrace = res.data || [];
|
|
}
|
|
});
|
|
},
|
|
|
|
// 关闭物流详情弹窗
|
|
closeLogisticsPopup() {
|
|
this.showLogisticsPopup = false;
|
|
},
|
|
|
|
// 确认收货
|
|
confirmReceipt() {
|
|
uni.showModal({
|
|
title: "确认收货",
|
|
content: "确认已收到所有商品吗?",
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
this.confirmReceiptApi();
|
|
}
|
|
},
|
|
});
|
|
},
|
|
|
|
// 确认收货API
|
|
confirmReceiptApi() {
|
|
uni.showLoading({
|
|
title: "确认中...",
|
|
});
|
|
|
|
this.Post({}, `/framework/ygOrder/finish/${this.orderId}`, "DES").then(
|
|
(res) => {
|
|
uni.hideLoading();
|
|
if (res.code == 200) {
|
|
uni.showToast({
|
|
title: "确认收货成功",
|
|
icon: "success",
|
|
});
|
|
setTimeout(() => {
|
|
this.loadOrderDetail();
|
|
}, 800);
|
|
} else {
|
|
uni.showToast({
|
|
title: res.msg || "确认收货失败",
|
|
icon: "none",
|
|
});
|
|
}
|
|
}
|
|
);
|
|
},
|
|
|
|
// 联系供应商
|
|
contactSupplier() {
|
|
uni.showToast({
|
|
title: "正在联系供应商",
|
|
icon: "none",
|
|
});
|
|
// 这里可以跳转到客服页面或其他联系方式
|
|
},
|
|
|
|
// 申请售后
|
|
applyAfterSale() {
|
|
// 参考iSoul页面的客服弹窗
|
|
uni.showModal({
|
|
title: "申请售后",
|
|
content:
|
|
"客服电话:0515-69186109\n服务时间:周一至周五\n9:00-12:00,13:00-18:00\n\n是否联系客服申请售后?",
|
|
confirmText: "联系客服",
|
|
success: (res) => {
|
|
if (res.confirm) {
|
|
// 拨打客服电话
|
|
uni.makePhoneCall({
|
|
phoneNumber: "0515-69186109",
|
|
});
|
|
}
|
|
},
|
|
});
|
|
},
|
|
|
|
// 复制订单号
|
|
copyOrderNo() {
|
|
uni.setClipboardData({
|
|
data: this.orderDetail.orderNo,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: "订单号已复制",
|
|
icon: "success",
|
|
});
|
|
},
|
|
});
|
|
},
|
|
|
|
// 复制快递单号
|
|
copyExpressCode() {
|
|
if (this.orderDetail.delivery && this.orderDetail.delivery.expressCode) {
|
|
uni.setClipboardData({
|
|
data: this.orderDetail.delivery.expressCode,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: "快递单号已复制",
|
|
icon: "success",
|
|
});
|
|
},
|
|
});
|
|
}
|
|
},
|
|
|
|
// 复制快递单号
|
|
copyExpressNo() {
|
|
if (this.orderDetail.expressNo) {
|
|
uni.setClipboardData({
|
|
data: this.orderDetail.expressNo,
|
|
success: () => {
|
|
uni.showToast({
|
|
title: "快递单号已复制",
|
|
icon: "success",
|
|
});
|
|
},
|
|
});
|
|
}
|
|
},
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.order-detail-container {
|
|
min-height: 100vh;
|
|
background-color: #f5f5f5;
|
|
}
|
|
|
|
// 状态头部
|
|
.status-header {
|
|
background-color: #fff;
|
|
padding: 20rpx 30rpx;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.status-badge {
|
|
padding: 8rpx 16rpx;
|
|
border-radius: 20rpx;
|
|
font-size: 24rpx;
|
|
color: #fff;
|
|
|
|
&.status-pending {
|
|
background-color: #ff9500;
|
|
}
|
|
|
|
&.status-paid {
|
|
background-color: #007aff;
|
|
}
|
|
|
|
&.status-cancelled {
|
|
background-color: #ff3b30;
|
|
}
|
|
|
|
&.status-shipping {
|
|
background-color: #34c759;
|
|
}
|
|
|
|
&.status-completed {
|
|
background-color: #48bb78;
|
|
}
|
|
}
|
|
|
|
.order-title {
|
|
font-size: 32rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
}
|
|
|
|
// 通用区域样式
|
|
.section-title {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 24rpx;
|
|
}
|
|
|
|
// 收货地址区域
|
|
.address-section {
|
|
background-color: #fff;
|
|
padding: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.address-card {
|
|
background-color: #f8f9fa;
|
|
border-radius: 12rpx;
|
|
padding: 24rpx;
|
|
}
|
|
|
|
.address-text {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
line-height: 1.5;
|
|
margin-bottom: 16rpx;
|
|
}
|
|
|
|
.contact-info {
|
|
display: flex;
|
|
gap: 20rpx;
|
|
}
|
|
|
|
.contact-name,
|
|
.contact-phone {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
}
|
|
|
|
// 商品列表
|
|
.goods-section {
|
|
background-color: #fff;
|
|
padding: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.goods-item {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
padding: 24rpx 0;
|
|
border-bottom: 1rpx solid #f0f0f0;
|
|
|
|
&:last-child {
|
|
border-bottom: none;
|
|
}
|
|
}
|
|
|
|
.goods-image-container {
|
|
margin-right: 20rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.goods-image {
|
|
width: 100rpx;
|
|
height: 100rpx;
|
|
border-radius: 10rpx;
|
|
}
|
|
|
|
.goods-content {
|
|
flex: 1;
|
|
}
|
|
|
|
.goods-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.goods-name {
|
|
font-size: 28rpx;
|
|
color: #333;
|
|
font-weight: 600;
|
|
margin-bottom: 8rpx;
|
|
line-height: 1.4;
|
|
}
|
|
|
|
.goods-quantity-price {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-top: 10rpx;
|
|
}
|
|
|
|
.goods-quantity {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.goods-price {
|
|
font-size: 26rpx;
|
|
color: #f56565;
|
|
font-weight: 600;
|
|
}
|
|
|
|
// 商品规格样式
|
|
.goods-specs {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 8rpx;
|
|
margin-bottom: 10rpx;
|
|
}
|
|
|
|
.spec-tag {
|
|
background: #f0f8ff;
|
|
border: 1rpx solid #e6f3ff;
|
|
border-radius: 12rpx;
|
|
padding: 4rpx 12rpx;
|
|
display: inline-block;
|
|
font-size: 22rpx;
|
|
color: #4a90e2;
|
|
font-weight: 500;
|
|
}
|
|
|
|
// 金额汇总
|
|
.amount-summary {
|
|
padding: 20rpx 0;
|
|
border-top: 1rpx solid #f0f0f0;
|
|
margin-top: 20rpx;
|
|
}
|
|
|
|
.summary-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 12rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
&.total-row {
|
|
padding-top: 12rpx;
|
|
border-top: 1rpx solid #f0f0f0;
|
|
margin-top: 12rpx;
|
|
}
|
|
}
|
|
|
|
.summary-label {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.summary-value {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
font-weight: 600;
|
|
|
|
&.total-amount {
|
|
font-size: 28rpx;
|
|
color: #f56565;
|
|
}
|
|
}
|
|
|
|
// 物流信息
|
|
.logistics-section {
|
|
background-color: #fff;
|
|
padding: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.logistics-card {
|
|
display: flex;
|
|
align-items: center;
|
|
background-color: #f8f9fa;
|
|
border-radius: 12rpx;
|
|
padding: 24rpx;
|
|
}
|
|
|
|
.logistics-info {
|
|
flex: 1;
|
|
}
|
|
|
|
.logistics-company {
|
|
margin-bottom: 8rpx;
|
|
}
|
|
|
|
.company-name {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
font-weight: 600;
|
|
margin-right: 12rpx;
|
|
}
|
|
|
|
.express-no {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.logistics-status {
|
|
font-size: 24rpx;
|
|
color: #007aff;
|
|
}
|
|
|
|
.logistics-arrow {
|
|
margin-left: 20rpx;
|
|
}
|
|
|
|
// 订单信息
|
|
.order-info-section {
|
|
background-color: #fff;
|
|
padding: 30rpx;
|
|
margin-bottom: 20rpx;
|
|
}
|
|
|
|
.info-row {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
margin-bottom: 20rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
}
|
|
|
|
.info-value {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
text-align: right;
|
|
}
|
|
|
|
// 底部按钮占位
|
|
.bottom-placeholder {
|
|
height: 180rpx;
|
|
padding-bottom: env(safe-area-inset-bottom);
|
|
}
|
|
|
|
// 底部操作
|
|
.bottom-actions {
|
|
position: fixed;
|
|
bottom: 0;
|
|
left: 0;
|
|
right: 0;
|
|
background-color: #fff;
|
|
padding: 20rpx 30rpx;
|
|
padding-bottom: calc(20rpx + min(env(safe-area-inset-bottom), 40rpx));
|
|
border-top: 1rpx solid #eee;
|
|
display: flex;
|
|
gap: 16rpx;
|
|
|
|
.action-btn-bottom {
|
|
flex: 1;
|
|
border-radius: 10rpx;
|
|
font-size: 26rpx;
|
|
font-weight: 600;
|
|
border: none;
|
|
color: #333333;
|
|
transition: all 0.3s ease;
|
|
text-align: center;
|
|
background-color: #77f3f9;
|
|
height: 88rpx;
|
|
align-items: center;
|
|
display: flex;
|
|
justify-content: center;
|
|
|
|
&.confirm-btn {
|
|
background-color: #48bb78;
|
|
color: #ffffff;
|
|
}
|
|
|
|
&.cancel-btn {
|
|
background-color: #ff3b30;
|
|
color: #ffffff;
|
|
}
|
|
|
|
&.contact-btn {
|
|
background-color: #007aff;
|
|
color: #ffffff;
|
|
}
|
|
|
|
&.after-sale-btn {
|
|
background-color: #ff4757;
|
|
color: #ffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 物流详情弹窗
|
|
.logistics-popup-mask {
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background-color: rgba(0, 0, 0, 0.5);
|
|
z-index: 9999;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
|
|
.logistics-popup {
|
|
width: 650rpx;
|
|
max-height: 80vh;
|
|
background-color: #fff;
|
|
border-radius: 20rpx;
|
|
overflow: hidden;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.popup-header {
|
|
display: flex;
|
|
justify-content: space-between;
|
|
align-items: center;
|
|
padding: 30rpx;
|
|
border-bottom: 1px solid #f0f0f0;
|
|
}
|
|
|
|
.popup-title {
|
|
font-size: 32rpx;
|
|
font-weight: bold;
|
|
color: #333;
|
|
}
|
|
|
|
.popup-close {
|
|
font-size: 40rpx;
|
|
color: #999;
|
|
}
|
|
|
|
.popup-content {
|
|
padding: 30rpx;
|
|
flex: 1;
|
|
overflow-y: auto;
|
|
}
|
|
|
|
.logistics-detail-section {
|
|
margin-bottom: 30rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
|
|
.detail-title {
|
|
font-size: 28rpx;
|
|
font-weight: 600;
|
|
color: #333;
|
|
margin-bottom: 16rpx;
|
|
border-left: 4rpx solid #007aff;
|
|
padding-left: 16rpx;
|
|
}
|
|
|
|
.logistics-status-info {
|
|
font-size: 26rpx;
|
|
color: #007aff;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.info-item {
|
|
display: flex;
|
|
align-items: center;
|
|
margin-bottom: 12rpx;
|
|
|
|
&:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
}
|
|
|
|
.info-label {
|
|
font-size: 26rpx;
|
|
color: #666;
|
|
min-width: 160rpx;
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.info-value {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
flex: 1;
|
|
}
|
|
|
|
// 物流轨迹
|
|
.trace-list {
|
|
.trace-item {
|
|
padding: 16rpx 0;
|
|
border-left: 2rpx solid #e2e8f0;
|
|
padding-left: 24rpx;
|
|
position: relative;
|
|
margin-bottom: 16rpx;
|
|
|
|
&:before {
|
|
content: "";
|
|
position: absolute;
|
|
left: -6rpx;
|
|
top: 20rpx;
|
|
width: 10rpx;
|
|
height: 10rpx;
|
|
border-radius: 50%;
|
|
background-color: #e2e8f0;
|
|
}
|
|
|
|
&.is-current {
|
|
border-left-color: #007aff;
|
|
|
|
&:before {
|
|
background-color: #007aff;
|
|
}
|
|
|
|
.trace-time,
|
|
.trace-status {
|
|
color: #007aff;
|
|
font-weight: 600;
|
|
}
|
|
}
|
|
|
|
&:last-child {
|
|
border-left-color: transparent;
|
|
}
|
|
}
|
|
}
|
|
|
|
.trace-time {
|
|
font-size: 22rpx;
|
|
color: #999;
|
|
margin-bottom: 6rpx;
|
|
}
|
|
|
|
.trace-status {
|
|
font-size: 26rpx;
|
|
color: #333;
|
|
margin-bottom: 4rpx;
|
|
}
|
|
|
|
.trace-location {
|
|
font-size: 22rpx;
|
|
color: #666;
|
|
}
|
|
</style>
|
|
|