From 86d03886b4b6ecfb6d55a1c7c037af2043103137 Mon Sep 17 00:00:00 2001 From: admin Date: Wed, 10 Jun 2026 22:13:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=95=86=E5=93=81=E8=AF=A6=E6=83=85?= =?UTF-8?q?=E9=A1=B5=E5=9B=BE=E7=89=87=E7=BC=A9=E6=94=BE=E6=98=BE=E7=A4=BA?= =?UTF-8?q?=E6=94=B9=E8=BF=9B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加缩略图列表切换功能 - 点击主图可放大预览 - 添加缩放提示文字 - 优化移动端样式 Co-Authored-By: Claude Fable 5 --- frontend/src/views/user/ProductDetail.vue | 134 ++++++++++++++++------ 1 file changed, 102 insertions(+), 32 deletions(-) diff --git a/frontend/src/views/user/ProductDetail.vue b/frontend/src/views/user/ProductDetail.vue index f6a36b7..14255e1 100644 --- a/frontend/src/views/user/ProductDetail.vue +++ b/frontend/src/views/user/ProductDetail.vue @@ -5,26 +5,39 @@
- - - - - - - - - - -
- + +
+ + + +
+ +
+
+ +
+
+ +
+ + 点击图片放大查看
@@ -65,7 +78,7 @@ import { ref, computed, onMounted } from 'vue' import { useRoute, useRouter } from 'vue-router' import { ElMessage } from 'element-plus' -import { Goods } from '@element-plus/icons-vue' +import { Goods, ZoomIn } from '@element-plus/icons-vue' import { productApi, userApi } from '../../api' import { useCartStore } from '../../store/cart' import { useI18n } from 'vue-i18n' @@ -79,12 +92,17 @@ const cartStore = useCartStore() const product = ref(null) const quantity = ref(1) const userCredits = ref(0) +const currentImageIndex = ref(0) const productImages = computed(() => { if (!product.value?.images) return [] return product.value.images.split(',').map((s: string) => s.trim()).filter(Boolean).map((url: string) => getImageUrl(url)) }) +const currentImage = computed(() => { + return productImages.value[currentImageIndex.value] || '' +}) + // 检查用户是否有足够资格购买 function hasEnoughCredit(): boolean { if (!product.value || !product.value.require_credit) return true @@ -139,17 +157,68 @@ function buyNow() { .product-detail-page { padding: 0; } .detail-card { background: #2d2d44; border: 1px solid rgba(255, 255, 255, 0.06); border-radius: 12px; padding: 32px; } .product-images { - height: 400px; background: rgba(255, 255, 255, 0.04); border-radius: 12px; overflow: hidden; - .carousel-image, .single-image { - width: 100%; + .main-image-wrap { height: 400px; display: flex; align-items: center; justify-content: center; + cursor: pointer; + + .main-image { + max-width: 100%; + max-height: 100%; + } + } + + .thumbnail-list { + display: flex; + gap: 8px; + padding: 12px; + background: rgba(0, 0, 0, 0.2); + + .thumbnail-item { + width: 60px; + height: 60px; + border-radius: 6px; + overflow: hidden; + cursor: pointer; + border: 2px solid transparent; + transition: all 0.2s; + opacity: 0.6; + + &:hover { + opacity: 0.9; + } + + &.active { + border-color: #4e6ef2; + opacity: 1; + } + + .thumbnail-image { + width: 100%; + height: 100%; + } + } + } + + .image-tip { + display: flex; + align-items: center; + justify-content: center; + gap: 4px; + padding: 8px; + background: rgba(0, 0, 0, 0.3); + color: rgba(255, 255, 255, 0.5); + font-size: 12px; + + .el-icon { + font-size: 14px; + } } .image-placeholder { @@ -208,15 +277,16 @@ h1 { font-size: 28px; color: #fff; margin-bottom: 16px; } } .product-images { - height: 300px; - } + .main-image-wrap { + height: 300px; + } - .carousel-image, .single-image { - height: 300px; - } - - .image-placeholder { - height: 300px; + .thumbnail-list { + .thumbnail-item { + width: 50px; + height: 50px; + } + } } h1 {