hookehuyr

feat(profile): 添加我的订单页面

在用户个人中心添加“我的订单”页面,展示用户的订单信息,包括订单号、状态、商品详情等。支持查看订单详情和支付功能。
...@@ -97,6 +97,12 @@ const routes = [ ...@@ -97,6 +97,12 @@ const routes = [
97 meta: { title: '我的课程' } 97 meta: { title: '我的课程' }
98 }, 98 },
99 { 99 {
100 + path: '/profile/orders',
101 + name: 'Orders',
102 + component: () => import('../views/profile/OrdersPage.vue'),
103 + meta: { title: '我的订单' }
104 + },
105 + {
100 path: '/profile/favorites', 106 path: '/profile/favorites',
101 name: 'MyFavorites', 107 name: 'MyFavorites',
102 component: () => import('../views/profile/MyFavoritesPage.vue'), 108 component: () => import('../views/profile/MyFavoritesPage.vue'),
......
1 +<!--
2 + * @Date: 2025-03-21
3 + * @Description: 我的订单页面
4 +-->
5 +<template>
6 + <AppLayout title="我的订单">
7 + <div class="bg-gradient-to-b from-green-50/70 to-white/90 min-h-screen pb-20">
8 + <!-- 订单列表 -->
9 + <van-list
10 + v-model:loading="loading"
11 + :finished="finished"
12 + finished-text="没有更多了"
13 + @load="onLoad"
14 + class="px-4 py-3 space-y-4"
15 + >
16 + <FrostedGlass
17 + v-for="order in orders"
18 + :key="order.id"
19 + class="p-4 rounded-xl"
20 + >
21 + <div class="flex items-center justify-between mb-3">
22 + <span class="text-sm text-gray-500">订单号:{{ order.orderNo }}</span>
23 + <span :class="['text-sm', order.statusColor]">{{ order.statusText }}</span>
24 + </div>
25 +
26 + <div class="flex items-center mb-3">
27 + <img :src="order.image" class="w-20 h-20 object-cover rounded-lg" :alt="order.title">
28 + <div class="ml-3 flex-1">
29 + <h3 class="text-base font-medium mb-1">{{ order.title }}</h3>
30 + <p class="text-sm text-gray-500 mb-1">{{ order.description }}</p>
31 + <p class="text-sm text-gray-500">{{ order.createTime }}</p>
32 + </div>
33 + </div>
34 +
35 + <div class="flex justify-between items-center pt-3 border-t border-gray-100">
36 + <div class="text-base font-medium text-green-600">¥{{ order.amount }}</div>
37 + <div class="space-x-2">
38 + <button
39 + v-if="order.status === 'pending'"
40 + class="px-4 py-1.5 text-sm text-white bg-green-600 rounded-full"
41 + @click="handlePay(order)"
42 + >
43 + 立即支付
44 + </button>
45 + <button
46 + v-if="order.status === 'paid'"
47 + class="px-4 py-1.5 text-sm text-gray-600 bg-gray-100 rounded-full"
48 + @click="handleViewDetail(order)"
49 + >
50 + 查看详情
51 + </button>
52 + </div>
53 + </div>
54 + </FrostedGlass>
55 + </van-list>
56 +
57 + <!-- 无数据提示 -->
58 + <div v-if="!loading && orders.length === 0" class="flex flex-col items-center justify-center py-12">
59 + <svg xmlns="http://www.w3.org/2000/svg" class="h-16 w-16 text-gray-300" fill="none" viewBox="0 0 24 24" stroke="currentColor">
60 + <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" />
61 + </svg>
62 + <p class="mt-4 text-gray-500">暂无订单记录</p>
63 + </div>
64 + </div>
65 + </AppLayout>
66 +</template>
67 +
68 +<script setup>
69 +import { ref } from 'vue'
70 +import { useRouter } from 'vue-router'
71 +import AppLayout from '@/components/layout/AppLayout.vue'
72 +import FrostedGlass from '@/components/ui/FrostedGlass.vue'
73 +
74 +const router = useRouter()
75 +const loading = ref(false)
76 +const finished = ref(false)
77 +const orders = ref([
78 + {
79 + id: 1,
80 + orderNo: 'ORDER202503210001',
81 + status: 'pending',
82 + statusText: '待支付',
83 + statusColor: 'text-orange-500',
84 + title: '亲子阅读课程',
85 + description: '3-6岁儿童亲子阅读指导',
86 + image: '/assets/images/course-1.jpg',
87 + amount: 299,
88 + createTime: '2025-03-21 10:30:00'
89 + },
90 + {
91 + id: 2,
92 + orderNo: 'ORDER202503210002',
93 + status: 'paid',
94 + statusText: '已支付',
95 + statusColor: 'text-green-500',
96 + title: '儿童绘画课程',
97 + description: '儿童创意绘画启蒙课程',
98 + image: '/assets/images/course-2.jpg',
99 + amount: 199,
100 + createTime: '2025-03-21 09:15:00'
101 + }
102 +])
103 +
104 +// 加载更多
105 +const onLoad = () => {
106 + // 模拟异步加载
107 + setTimeout(() => {
108 + loading.value = false
109 + finished.value = true
110 + }, 1000)
111 +}
112 +
113 +// 支付订单
114 +const handlePay = (order) => {
115 + router.push(`/checkout/${order.id}`)
116 +}
117 +
118 +// 查看订单详情
119 +const handleViewDetail = (order) => {
120 + router.push(`/profile/orders/${order.id}`)
121 +}
122 +</script>