fix: 恢复商品详情页图片显示,使用scale-down确保图片完整显示
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -5,39 +5,26 @@
|
|||||||
<el-row :gutter="32">
|
<el-row :gutter="32">
|
||||||
<el-col :span="12">
|
<el-col :span="12">
|
||||||
<div class="product-images">
|
<div class="product-images">
|
||||||
<!-- 主图显示 -->
|
<el-carousel v-if="productImages.length > 1" height="400px" :autoplay="false" indicator-position="outside">
|
||||||
<div class="main-image-wrap">
|
<el-carousel-item v-for="(img, index) in productImages" :key="index">
|
||||||
<el-image
|
<el-image :src="img" fit="scale-down" class="carousel-image" :preview-src-list="productImages" :initial-index="index">
|
||||||
:src="currentImage"
|
<template #error>
|
||||||
fit="contain"
|
<div class="image-placeholder">
|
||||||
class="main-image"
|
<el-icon size="80"><Goods /></el-icon>
|
||||||
:preview-src-list="productImages"
|
</div>
|
||||||
:initial-index="currentImageIndex"
|
</template>
|
||||||
:z-index="9999"
|
</el-image>
|
||||||
>
|
</el-carousel-item>
|
||||||
<template #error>
|
</el-carousel>
|
||||||
<div class="image-placeholder">
|
<el-image v-else-if="productImages.length === 1" :src="productImages[0]" fit="scale-down" class="single-image" :preview-src-list="productImages">
|
||||||
<el-icon size="80"><Goods /></el-icon>
|
<template #error>
|
||||||
</div>
|
<div class="image-placeholder">
|
||||||
</template>
|
<el-icon size="80"><Goods /></el-icon>
|
||||||
</el-image>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<!-- 缩略图列表 -->
|
</el-image>
|
||||||
<div class="thumbnail-list" v-if="productImages.length > 1">
|
<div v-else class="image-placeholder empty">
|
||||||
<div
|
<el-icon size="80"><Goods /></el-icon>
|
||||||
v-for="(img, index) in productImages"
|
|
||||||
:key="index"
|
|
||||||
class="thumbnail-item"
|
|
||||||
:class="{ active: currentImageIndex === index }"
|
|
||||||
@click="currentImageIndex = index"
|
|
||||||
>
|
|
||||||
<el-image :src="img" fit="cover" class="thumbnail-image" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<!-- 单图提示 -->
|
|
||||||
<div class="image-tip" v-if="productImages.length > 0">
|
|
||||||
<el-icon><ZoomIn /></el-icon>
|
|
||||||
<span>点击图片放大查看</span>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</el-col>
|
</el-col>
|
||||||
@@ -78,7 +65,7 @@
|
|||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { useRoute, useRouter } from 'vue-router'
|
import { useRoute, useRouter } from 'vue-router'
|
||||||
import { ElMessage } from 'element-plus'
|
import { ElMessage } from 'element-plus'
|
||||||
import { Goods, ZoomIn } from '@element-plus/icons-vue'
|
import { Goods } from '@element-plus/icons-vue'
|
||||||
import { productApi, userApi } from '../../api'
|
import { productApi, userApi } from '../../api'
|
||||||
import { useCartStore } from '../../store/cart'
|
import { useCartStore } from '../../store/cart'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
@@ -92,17 +79,12 @@ const cartStore = useCartStore()
|
|||||||
const product = ref<any>(null)
|
const product = ref<any>(null)
|
||||||
const quantity = ref(1)
|
const quantity = ref(1)
|
||||||
const userCredits = ref(0)
|
const userCredits = ref(0)
|
||||||
const currentImageIndex = ref(0)
|
|
||||||
|
|
||||||
const productImages = computed(() => {
|
const productImages = computed(() => {
|
||||||
if (!product.value?.images) return []
|
if (!product.value?.images) return []
|
||||||
return product.value.images.split(',').map((s: string) => s.trim()).filter(Boolean).map((url: string) => getImageUrl(url))
|
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 {
|
function hasEnoughCredit(): boolean {
|
||||||
if (!product.value || !product.value.require_credit) return true
|
if (!product.value || !product.value.require_credit) return true
|
||||||
@@ -157,68 +139,18 @@ function buyNow() {
|
|||||||
.product-detail-page { padding: 0; }
|
.product-detail-page { padding: 0; }
|
||||||
.detail-card { background: #2d2d44; border: 1px solid rgba(255, 255, 255, 0.06); border-radius: 12px; padding: 32px; }
|
.detail-card { background: #2d2d44; border: 1px solid rgba(255, 255, 255, 0.06); border-radius: 12px; padding: 32px; }
|
||||||
.product-images {
|
.product-images {
|
||||||
|
height: 400px;
|
||||||
background: rgba(255, 255, 255, 0.04);
|
background: rgba(255, 255, 255, 0.04);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
.main-image-wrap {
|
.carousel-image, .single-image {
|
||||||
|
width: 100%;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
cursor: pointer;
|
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 {
|
.image-placeholder {
|
||||||
@@ -230,6 +162,10 @@ function buyNow() {
|
|||||||
background: rgba(255, 255, 255, 0.04);
|
background: rgba(255, 255, 255, 0.04);
|
||||||
color: rgba(255, 255, 255, 0.2);
|
color: rgba(255, 255, 255, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image-placeholder.empty {
|
||||||
|
height: 400px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h1 { font-size: 28px; color: #fff; margin-bottom: 16px; }
|
h1 { font-size: 28px; color: #fff; margin-bottom: 16px; }
|
||||||
.price { font-size: 32px; font-weight: 700; color: #4e6ef2; margin-bottom: 16px; }
|
.price { font-size: 32px; font-weight: 700; color: #4e6ef2; margin-bottom: 16px; }
|
||||||
@@ -277,16 +213,15 @@ h1 { font-size: 28px; color: #fff; margin-bottom: 16px; }
|
|||||||
}
|
}
|
||||||
|
|
||||||
.product-images {
|
.product-images {
|
||||||
.main-image-wrap {
|
height: 300px;
|
||||||
height: 300px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.thumbnail-list {
|
.carousel-image, .single-image {
|
||||||
.thumbnail-item {
|
height: 300px;
|
||||||
width: 50px;
|
}
|
||||||
height: 50px;
|
|
||||||
}
|
.image-placeholder {
|
||||||
}
|
height: 300px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
|||||||
Reference in New Issue
Block a user