<script setup lang="ts"> import { onMounted } from 'vue' import { useOrderStore } from '@/pinia/stores/order' import { useRoute, useRouter } from 'vue-router' const orderStore = useOrderStore() const route = useRoute() const router = useRouter() const statusMap: Record<number, string> = { 1: '待付款', 2: '已付款', 3: '已发货', 4: '已完成', 5: '已取消' } const getStatusText = (status: number) => { return statusMap[status] || '未知状态' } const orderId = ref(parseInt(String(route.params.id))) // 监听路由参数变化 watch(() => route.params.id, (newId) => { orderId.value = parseInt(String(newId)) }) const order = computed(() => { return orderStore.orders.find(o => o.orderId === orderId.value) }) const handleRefund = (item: any) => { if (order.value?.status !== 4) return router.push({ path: '/approval/submit', query: { goodsId: item.goodsInfo.goodsId, orderId: order.value.orderId } }) } onMounted(() => { if (!order.value) { // 订单不存在处理 } }) </script> <template> <div class="order-detail" v-if="order"> <h2>订单详情</h2> <div class="order-info"> <p>订单号: {{ order.orderId }}</p> <p>状态: {{ getStatusText(order.status) }}</p> <p>总价: ¥{{ order.totalAmount }}</p> <p>支付时间: {{ order.payTime }}</p> </div> <van-cell-group class="goods-list"> <van-cell v-for="(item, index) in order.goodsList" :key="index" class="goods-item" > <template #icon> <van-image :src="item.goodsInfo.coverImg" width="80" height="80" class="product-image" /> </template> <div class="product-info"> <div class="product-name-price"> <div class="product-name van-ellipsis"> {{ item.goodsInfo.goodsName }} </div> <div class="product-price"> ¥{{ item.orderGoods.price.toFixed(2) }} </div> </div> <div class="action-row"> <p>数量: {{ item.orderGoods.quantity }}</p> <p>小计: ¥{{ (item.orderGoods.price * item.orderGoods.quantity).toFixed(2) }}</p> <van-button v-if="order.status === 4" type="primary" size="mini" class="refund-btn" @click="handleRefund(item)" > 退还 </van-button> </div> </div> </van-cell> </van-cell-group> </div> <div v-else class="not-found"> 订单不存在或已失效 </div> </template> <style scoped> .order-detail { padding: 20px; } .order-info { padding: 15px; margin-bottom: 20px; background: #f5f5f5; border-radius: 8px; } .goods-list { padding: 15px; background: #fff; border-radius: 8px; } .goods-item { display: flex; padding: 15px 0; border-bottom: 1px solid #f5f5f5; } goods-item:last-child { border-bottom: none; } goods-item img { width: 100px; height: 100px; object-fit: cover; margin-right: 15px; } goods-info { flex: 1; } .product-name-price { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; } .product-name { flex: 1; margin-right: 10px; } .product-price { color: #ee0a24; font-weight: 500; } .not-found { padding: 40px; text-align: center; color: #999; } .refund-btn { margin-left: auto; color: #fff; background: #ee0a24; border-radius: 15px; padding: 0 12px; } .action-row { display: flex; gap: 8px; align-items: center; } </style>