From 6e0ae59f436f8a8c662bea4bd68eadaba070ef2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=A4=A7=E8=84=8F=E7=8B=BC?= <786316265@qq.com> Date: Fri, 29 Aug 2025 16:58:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=95=86=E5=9F=8E=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/router/index.js | 8 +- src/views/BuyDetails.vue | 55 +++-- src/views/Cart.vue | 42 ++-- src/views/MyShop.vue | 7 + src/views/Orders.vue | 221 +++++++++++++++-- src/views/Pay.vue | 444 +++++++++++++++-------------------- src/views/PayLoading.vue | 151 ++++++------ src/views/ProductDetail.vue | 67 ++---- src/views/ProductSummary.vue | 35 ++- src/views/Shop.vue | 28 ++- 10 files changed, 613 insertions(+), 445 deletions(-) diff --git a/src/router/index.js b/src/router/index.js index e7f424d..4310392 100644 --- a/src/router/index.js +++ b/src/router/index.js @@ -245,11 +245,11 @@ const routes = [ meta: { title: '确认订单' } }, { - path: '/pay', + path: '/pay/:orderId', name: 'Pay', component: () => import('@/views/Pay.vue'), meta: { title: '确认支付' }, - props: route => ({ cartId: route.query.cartId }) + props: route => ({ orderId: route.query.orderId }) }, { path: '/cart', @@ -266,9 +266,9 @@ const routes = [ { path: '/payloading', name: 'PayLoading', - component: () => import('../views/PayLoading.vue'), + component: () => import('@/views/PayLoading.vue'), meta: { title: '支付确认' }, - props: route => ({ cartId: route.query.cartId }) + props: route => ({ orderId: route.query.orderId }) }, { path: '/:pathMatch(.*)*', diff --git a/src/views/BuyDetails.vue b/src/views/BuyDetails.vue index 5b6bb47..423af47 100644 --- a/src/views/BuyDetails.vue +++ b/src/views/BuyDetails.vue @@ -366,31 +366,42 @@ const handlePurchase = async () => { } try { - // 构建商品数据,直接跳转到Pay页面 - const purchaseData = { - items: [{ - id: product.value.id, - productId: product.value.id, - name: product.value.name, - image: product.value.image, - points: product.value.points, - quantity: quantity.value, - specificationId: specificationId, - specs: Object.keys(selectedSpecs.value).map(specName => - `${specName}: ${selectedSpecs.value[specName].name}` - ).join(', '), - orderNote: orderNote.value - }] + // 先将商品添加到购物车 + const cartItem = { + productId: product.value.id, + quantity: quantity.value, + specificationId: specificationId, + points: product.value.points, + name: product.value.name, + image: product.value.image, + stock: product.value.stock + } + + const addToCartResponse = await api.post('/cart/add', cartItem) + + if (!addToCartResponse.data.success) { + throw new Error(addToCartResponse.data.message || '添加到购物车失败') + } + + // 获取刚添加的购物车项ID + const cartItemId = addToCartResponse.data.data?.cart_item_id || addToCartResponse.data.data?.id || addToCartResponse.data.data?.cartItemId || addToCartResponse.data.id + + if (!cartItemId) { + console.error('添加购物车API响应:', addToCartResponse.data) + throw new Error('无法获取购物车项ID') } - // 跳转到Pay页面,传递商品数据 - router.push({ - path: '/pay', - query: { - from: 'buydetails', - cartData: JSON.stringify(purchaseData) - } + // 创建订单 + const response = await api.post('/orders/create-from-cart', { + cart_item_ids: [cartItemId] }) + + if (response.data.success) { + // 跳转到Pay页面 + router.push(`/pay/${response.data.data.preOrderId}`) + } else { + throw new Error(response.data.message || '创建订单失败') + } } catch (error) { ElMessage.error(error.message || '操作失败,请重试') } diff --git a/src/views/Cart.vue b/src/views/Cart.vue index d92443d..28183c8 100644 --- a/src/views/Cart.vue +++ b/src/views/Cart.vue @@ -80,23 +80,19 @@
- - - +
{{ item.quantity }} - + - +
{ const selectedIds = selectedItems.value.map(item => item.id) // 向后端发送选中商品的id数组创建订单 - const response = await api.post('/order/create-from-cart', { + const response = await api.post('/orders/create-from-cart', { cart_item_ids: selectedIds }) if (response.data.success) { // 直接跳转到支付页面,不传递任何参数 - router.push('/pay') + console.log('跳转支付页面的response',response.data.data.preOrderId) + router.push(`/pay/${response.data.data.preOrderId}`) } else { throw new Error(response.data.message || '创建订单失败') } @@ -337,6 +334,12 @@ onMounted(() => { flex: 1; } +.nav-right { + display: flex; + justify-content: center; + align-items: center; +} + .nav-center { flex: 2; text-align: center; @@ -500,8 +503,6 @@ onMounted(() => { .quantity-controls { display: flex; align-items: center; - border: 1px solid #e0e0e0; - border-radius: 4px; overflow: hidden; } @@ -510,22 +511,27 @@ onMounted(() => { height: 32px; padding: 0; border: none; - background: #f5f5f5; + background: transparent; color: #666; font-size: 16px; font-weight: 600; display: flex; align-items: center; justify-content: center; + cursor: pointer; + user-select: none; } .quantity-btn:hover { - background: #e0e0e0; + background: transparent; + color: #333; } -.quantity-btn:disabled { - background: #f9f9f9; +.quantity-btn.disabled { + background: transparent; color: #ccc; + cursor: not-allowed; + pointer-events: none; } .quantity { diff --git a/src/views/MyShop.vue b/src/views/MyShop.vue index 9dabaee..16e01ce 100644 --- a/src/views/MyShop.vue +++ b/src/views/MyShop.vue @@ -76,6 +76,8 @@ import { useRouter } from 'vue-router' import api from '@/utils/api' // 确保导入正确的api模块 import { ElMessage } from 'element-plus' +import {getImageUrl} from '@/config' + export default { setup() { const router = useRouter() @@ -121,6 +123,11 @@ export default { // 只取前3个商品作为精选商品 featuredProducts.value = data.data.products.slice(0, 3) + featuredProducts.value.forEach(product => { + if (product.image) { + product.image = getImageUrl(product.image) + } + }) } catch (error) { console.error('获取商品列表失败:', error) ElMessage.error('获取商品列表失败') diff --git a/src/views/Orders.vue b/src/views/Orders.vue index f4f984a..1acc35a 100644 --- a/src/views/Orders.vue +++ b/src/views/Orders.vue @@ -73,10 +73,17 @@

{{ item.product.name }}

{{ truncateText(item.product.description, 40) }}

- - - {{ item.points }} - +
+ + + {{ item.points }} + + + + + 融豆 + {{ item.rongdouPrice }} + +
x{{ item.quantity }}
@@ -86,12 +93,21 @@
- 共{{ order.totalQuantity }}件商品 - - 总计:{{ order.totalPoints }} - + 共{{ order.totalQuantity }}件商品 +
+ 总计: +
+ + {{ order.totalPoints }} + + + + + 融豆{{ order.totalRongdou }} + +
+
@@ -202,10 +218,18 @@ 订单号: {{ orderDetail.orderNumber }}
+
+ 用户名: + {{ orderDetail.username || '未知用户' }} +
下单时间: {{ formatDateTime(orderDetail.createdAt) }}
+
+ 更新时间: + {{ formatDateTime(orderDetail.updatedAt) }} +
订单状态: @@ -223,8 +247,14 @@
{{ item.product.name }}

{{ item.product.description }}

+

规格:{{ item.specInfo }}

- {{ item.points }} x {{ item.quantity }} +
+ {{ item.points }} + + + 融豆{{ item.rongdouPrice }} +
+ x {{ item.quantity }}
@@ -246,11 +276,23 @@

费用明细

商品总计: - {{ orderDetail.totalPoints }} +
+ + {{ orderDetail.totalPoints }} + + + 融豆{{ orderDetail.totalRongdou }} + +
- 实付积分: - {{ orderDetail.totalPoints }} + 实付: +
+ + {{ orderDetail.totalPoints }} + + + 融豆{{ orderDetail.totalRongdou }} + +
@@ -331,6 +373,17 @@ const getStatusType = (status) => { return typeMap[status] || 'info' } +const mapOrderStatus = (backendStatus) => { + const statusMap = { + 'pre_order': 'pending', + 'pending': 'pending', + 'shipped': 'shipped', + 'completed': 'completed', + 'cancelled': 'cancelled' + } + return statusMap[backendStatus] || 'pending' +} + const getStatusText = (status) => { const textMap = { pending: '待发货', @@ -451,13 +504,40 @@ const submitReview = async () => { } } -const viewOrderDetail = async (orderId) => { +const viewOrderDetail = (orderId) => { try { - const response = await api.get(`/orders/${orderId}`) - orderDetail.value = response.data + console.log('正在查找订单详情,订单ID:', orderId) + + // 从已加载的订单列表中查找对应订单 + const order = orders.value.find(o => o.id === orderId) + console.log('找到的订单数据:', order) + + if (!order) { + ElMessage.error('未找到订单信息') + return + } + + // 直接使用已映射的订单数据 + orderDetail.value = { + id: order.id, + orderNumber: order.orderNumber, + createdAt: order.createdAt, + updatedAt: order.updatedAt || order.createdAt, + username: order.username || '未知用户', + status: order.status, + totalPoints: order.totalPoints, + totalRongdou: order.totalRongdou, + totalQuantity: order.totalQuantity, + items: order.items || [], + shippingAddress: order.shippingAddress || null, + trackingNumber: order.trackingNumber || null + } + + console.log('设置的订单详情数据:', orderDetail.value) showOrderDetail.value = true } catch (error) { - ElMessage.error('获取订单详情失败') + console.error('查看订单详情失败:', error) + ElMessage.error(`查看订单详情失败: ${error.message || '未知错误'}`) } } @@ -478,13 +558,41 @@ const getOrders = async (isLoadMore = false) => { }) console.log(data,'response'); + // 映射后端数据结构到前端需要的格式 + const mappedOrders = data.data.orders.map(order => ({ + id: order.id, + orderNumber: order.order_no, + createdAt: order.created_at, + updatedAt: order.updated_at, + username: order.username, + status: mapOrderStatus(order.status), + totalPoints: order.total_points, + totalRongdou: order.total_rongdou, + totalQuantity: order.items?.reduce((sum, item) => sum + item.quantity, 0) || 0, + items: order.items?.map(item => ({ + id: item.id, + productId: item.product_id, + quantity: item.quantity, + points: item.points_price, + rongdouPrice: item.rongdou_price, + specInfo: item.spec_info, + product: { + name: item.product_name || '商品名称', + description: item.description || '商品描述', + image: item.image_url || '/imgs/loading.png' + } + })) || [], + shippingAddress: order.address || null, + trackingNumber: null + })) + if (isLoadMore) { - orders.value.push(...data.data.orders) + orders.value.push(...mappedOrders) } else { - orders.value = data.data.orders + orders.value = mappedOrders } - hasMore.value = data.data.hasMore + hasMore.value = data.data.pagination.page < data.data.pagination.pages page.value++ updateStatusCounts() @@ -702,6 +810,12 @@ onMounted(() => { align-items: center; } +.price-group { + display: flex; + align-items: center; + gap: 4px; +} + .price { display: flex; align-items: center; @@ -711,6 +825,30 @@ onMounted(() => { font-size: 14px; } +.plus-sign { + color: #999; + font-size: 12px; + margin: 0 2px; +} + +.rongdou-icon { + width: 14px; + height: 14px; + object-fit: contain; +} + +.detail-price-group { + display: flex; + align-items: center; + gap: 4px; +} + +.detail-item-price-group { + display: flex; + align-items: center; + gap: 4px; +} + .quantity { color: #999; font-size: 12px; @@ -728,7 +866,20 @@ onMounted(() => { align-items: center; } -.total-points { +.total-price { + display: flex; + align-items: center; + gap: 8px; +} + +.total-price-group { + display: flex; + align-items: center; + gap: 4px; +} + +.total-points, +.total-rongdou { display: flex; align-items: center; gap: 4px; @@ -877,6 +1028,13 @@ onMounted(() => { } .detail-product .product-price { + display: flex; + align-items: center; + justify-content: space-between; + gap: 8px; +} + +.detail-item-price-group { display: flex; align-items: center; gap: 4px; @@ -885,6 +1043,29 @@ onMounted(() => { font-size: 14px; } +.quantity-text { + color: #999; + font-size: 12px; +} + +.detail-price-group { + display: flex; + align-items: center; + gap: 4px; + color: #ff6b35; + font-weight: 600; +} + +.spec-info { + font-size: 12px; + color: #666; + margin: 4px 0; + background: #f5f5f5; + padding: 2px 8px; + border-radius: 4px; + display: inline-block; +} + /* 响应式设计 */ @media (max-width: 480px) { .order-header { diff --git a/src/views/Pay.vue b/src/views/Pay.vue index 985693d..ec15865 100644 --- a/src/views/Pay.vue +++ b/src/views/Pay.vue @@ -64,66 +64,36 @@ - -
-
- 订单商品 -
- -
-
-
- -
-
-
{{ item.name }}
-
{{ item.specs }}
-
- {{ item.points }}积分 - x{{ item.quantity }} -
-
-
- {{ item.points * item.quantity }}积分 -
-
-
- -
-

暂无商品信息

-
-
-

支付

- -