Files
apple 079076a70e miao33: 从 main 同步 single_uniapp22miao,dart-sass 兼容修复,DEPLOY.md 更新
- 从 main 获取 single_uniapp22miao 子项目
- dart-sass: /deep/ -> ::v-deep,calc 运算符加空格
- DEPLOY.md 采用 shccd159 版本(4 子项目架构说明)

Made-with: Cursor
2026-03-16 11:16:42 +08:00

545 lines
12 KiB
Vue
Raw Permalink 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.
<template>
<view class="order-detail-page">
<!-- 状态栏 -->
<view class="status-bar" :class="'status-' + orderInfo.status">
<text class="status-icon">{{ getStatusIcon() }}</text>
<text class="status-text">{{ getStatusText() }}</text>
</view>
<!-- 地址信息 -->
<view class="address-section" v-if="orderInfo.consignee">
<view class="section-title">
<text>收货信息</text>
</view>
<view class="address-content">
<view class="user-info">
<text class="name">{{ orderInfo.consignee }}</text>
<text class="phone">{{ orderInfo.phone }}</text>
</view>
<view class="address">
{{ orderInfo.province }} {{ orderInfo.city }}
{{ orderInfo.area }} {{ orderInfo.address }}
</view>
<view class="delivery-method">
<text>提货方式{{ orderInfo.delivery_method || '线下提货' }}</text>
</view>
</view>
</view>
<!-- 商品信息 -->
<view class="goods-section">
<view class="goods-item">
<image :src="getGoodsImage()" class="goods-image"></image>
<view class="goods-info">
<view class="goods-name">{{ getGoodsTitle() }}</view>
<view class="goods-spec">规格默认</view>
<view class="seller-info">
<text class="seller-label">卖家</text>
<text class="seller-name">{{ getSellerName() }}</text>
</view>
<view class="seller-phone">
<text class="phone-label">卖家电话</text>
<text class="phone-number">{{ getSellerPhone() }}</text>
</view>
</view>
<view class="goods-right">
<view class="goods-price">¥{{ orderInfo.total_money }}</view>
<view class="goods-num">x1</view>
</view>
</view>
</view>
<!-- 协议部分 -->
<view class="agreement-section">
<view class="agreement-item">
<text class="agreement-icon"></text>
<text class="agreement-text">购买委托代卖协议</text>
</view>
</view>
<!-- 底部操作栏 -->
<view class="bottom-bar" v-if="orderInfo.status != 3">
<button
v-if="orderInfo.status == 0"
class="btn cancel-btn"
@click="cancelOrder"
>
取消订单
</button>
<button
v-if="orderInfo.status == 0"
class="btn primary-btn"
@click="payOrder"
>
确认付款
</button>
<button
v-if="orderInfo.status == 1"
class="btn primary-btn"
@click="confirmOrder"
>
确认收货
</button>
<button
v-if="orderInfo.status == 2"
class="btn primary-btn"
@click="resellOrder"
>
转卖
</button>
</view>
</view>
</template>
<script>
import { getOrderDetail, cancelOrder, payOrder as payOrderAPI, confirmOrder as confirmOrderAPI, resellOrder as resellOrderAPI } from '@/api/miao.js';
export default {
data() {
return {
orderId: null,
orderInfo: {},
autoPay: false
}
},
onLoad(options) {
this.orderId = options.id;
this.autoPay = options.pay == '1';
this.loadOrderDetail();
},
methods: {
// 加载订单详情
async loadOrderDetail() {
try {
// 使用正确导入的API函数获取订单详情
const res = await getOrderDetail(this.orderId);
if (res.code === 0) {
this.orderInfo = res.data;
// 如果需要自动支付
if (this.autoPay && this.orderInfo.status == 0) {
this.payOrder();
}
}
} catch (error) {
console.error('加载订单详情失败:', error);
uni.showToast({
title: '加载失败',
icon: 'none'
});
}
},
// 获取状态图标
getStatusIcon() {
const iconMap = {
0: '⏰',
1: '🚚',
2: '✅',
3: '❌'
};
return iconMap[this.orderInfo.status] || '';
},
// 获取状态文本
getStatusText() {
const textMap = {
0: '待支付',
1: '已支付,等待确认',
2: '订单已完成',
3: '订单已取消'
};
return textMap[this.orderInfo.status] || '';
},
// 获取商品图片
getGoodsImage() {
// 适配可能的数据结构变化,确保即使数据格式不同也能正常显示
return this.orderInfo.goods_image || (this.orderInfo.goods && this.orderInfo.goods.image) || '';
},
// 获取商品标题
getGoodsTitle() {
return this.orderInfo.goods_name || (this.orderInfo.goods && this.orderInfo.goods.title) || '';
},
// 获取卖家姓名
getSellerName() {
return this.orderInfo.seller_name || (this.orderInfo.seller && this.orderInfo.seller.nickname) || '';
},
// 获取卖家电话
getSellerPhone() {
return this.orderInfo.seller_phone || (this.orderInfo.seller && this.orderInfo.seller.mobile) || '';
},
// 取消订单
cancelOrder() {
uni.showModal({
title: '提示',
content: '确定要取消该订单吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await cancelOrder({ id: this.orderId });
if (result.code === 0) {
this.orderInfo.status = 3;
uni.showToast({
title: '订单已取消',
icon: 'success'
});
} else {
uni.showToast({
title: result.msg || '取消失败',
icon: 'none'
});
}
} catch (error) {
console.error('取消订单失败:', error);
uni.showToast({
title: error.msg || '取消失败',
icon: 'none'
});
}
}
}
});
},
// 支付订单
async payOrder() {
try {
const res = await payOrderAPI({ id: this.orderId });
if (res.code === 0) {
// 处理支付结果
if (res.data && res.data.pay_url) {
// 如果有支付链接,跳转到支付页面
uni.navigateTo({
url: `/pages/users/user_payment/user_payment?pay_url=${encodeURIComponent(res.data.pay_url)}`
});
} else {
uni.showToast({
title: '支付成功',
icon: 'success'
});
// 刷新订单详情
setTimeout(() => {
this.loadOrderDetail();
}, 1500);
}
} else {
uni.showToast({
title: res.msg || '支付失败',
icon: 'none'
});
}
} catch (error) {
console.error('支付订单失败:', error);
uni.showToast({
title: error.msg || '支付失败',
icon: 'none'
});
}
},
// 确认收货
confirmOrder() {
uni.showModal({
title: '提示',
content: '确认收到货物了吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await confirmOrderAPI({ id: this.orderId });
if (result.code === 0) {
this.orderInfo.status = 2;
uni.showToast({
title: '确认成功',
icon: 'success'
});
} else {
uni.showToast({
title: result.msg || '确认失败',
icon: 'none'
});
}
} catch (error) {
console.error('确认收货失败:', error);
uni.showToast({
title: error.msg || '确认失败',
icon: 'none'
});
}
}
}
});
},
// 转卖订单
resellOrder() {
uni.showModal({
title: '提示',
content: '确定要将该订单转卖吗?',
success: async (res) => {
if (res.confirm) {
try {
const result = await resellOrderAPI({ id: this.orderId });
if (result.code === 0) {
uni.showToast({
title: '转卖成功',
icon: 'success'
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
} else {
uni.showToast({
title: result.msg || '转卖失败',
icon: 'none'
});
}
} catch (error) {
console.error('转卖订单失败:', error);
uni.showToast({
title: error.msg || '转卖失败',
icon: 'none'
});
}
}
}
});
}
}
}
</script>
<style lang="scss" scoped>
.order-detail-page {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 120rpx;
}
.status-bar {
padding: 30rpx;
text-align: center;
color: #fff;
&.status-0 {
background: linear-gradient(135deg, #FF6B6B, #FF4757);
}
&.status-1 {
background: linear-gradient(135deg, #FF9800, #FF5722);
}
&.status-2 {
background: linear-gradient(135deg, #4CAF50, #45a049);
}
&.status-3 {
background: linear-gradient(135deg, #999, #666);
}
.status-icon {
font-size: 60rpx;
display: block;
margin-bottom: 10rpx;
}
.status-text {
font-size: 28rpx;
font-weight: bold;
}
}
.address-section,
.goods-section,
.agreement-section {
background-color: #fff;
margin: 20rpx 0;
padding: 30rpx;
}
.section-title {
margin-bottom: 20rpx;
text {
font-size: 28rpx;
color: #333;
font-weight: bold;
}
}
.address-content {
.user-info {
margin-bottom: 15rpx;
.name {
font-size: 30rpx;
font-weight: bold;
color: #333;
margin-right: 20rpx;
}
.phone {
font-size: 28rpx;
color: #666;
}
}
.address {
font-size: 26rpx;
color: #666;
line-height: 1.5;
margin-bottom: 15rpx;
}
.delivery-method {
font-size: 26rpx;
color: #666;
}
}
.goods-item {
display: flex;
.goods-image {
width: 180rpx;
height: 180rpx;
border-radius: 8rpx;
margin-right: 20rpx;
background-color: #f5f5f5;
}
.goods-info {
flex: 1;
.goods-name {
font-size: 30rpx;
color: #333;
margin-bottom: 15rpx;
line-height: 1.4;
}
.goods-spec {
font-size: 26rpx;
color: #666;
margin-bottom: 15rpx;
}
.seller-info {
margin-bottom: 10rpx;
.seller-label {
font-size: 26rpx;
color: #666;
margin-right: 10rpx;
}
.seller-name {
font-size: 26rpx;
color: #FF6B6B;
background-color: #FFF0F0;
padding: 2rpx 10rpx;
border-radius: 4rpx;
}
}
.seller-phone {
.phone-label {
font-size: 26rpx;
color: #666;
}
.phone-number {
font-size: 26rpx;
color: #333;
}
}
}
.goods-right {
text-align: right;
.goods-price {
font-size: 32rpx;
color: #FF4757;
font-weight: bold;
margin-bottom: 10rpx;
}
.goods-num {
font-size: 28rpx;
color: #999;
}
}
}
.agreement-section {
margin-top: 40rpx;
.agreement-item {
display: flex;
align-items: center;
.agreement-icon {
font-size: 24rpx;
color: #FF6B6B;
margin-right: 10rpx;
}
.agreement-text {
font-size: 26rpx;
color: #FF6B6B;
}
}
}
.bottom-bar {
position: fixed;
bottom: 0;
left: 0;
right: 0;
display: flex;
align-items: center;
justify-content: flex-end;
gap: 20rpx;
padding: 20rpx 30rpx;
background-color: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
.btn {
height: 80rpx;
line-height: 80rpx;
padding: 0 50rpx;
border-radius: 40rpx;
font-size: 30rpx;
border: none;
font-weight: bold;
&.cancel-btn {
background-color: #f5f5f5;
color: #666;
}
&.primary-btn {
background: linear-gradient(90deg, #FF6B6B, #FF4757);
color: #fff;
flex: 1;
text-align: center;
}
}
}
</style>