feat: 景区首页及商品详情头图展示优化调整,支持轮播

This commit is contained in:
zoujing committed 2026-08-12 11:49:50 +08:00
1 parent b066de2c8c
commit d5a92e1dae
4 files changed
+120 -51

No files matched your search

@@ -2,24 +2,15 @@
<view class="flex h-full min-w-0 flex-col overflow-hidden bg-slate-100">
<scroll-view class="min-h-0 flex-1" scroll-y>
<view v-if="productImages.length" class="relative h-56 overflow-hidden bg-white">
<image class="h-full w-full bg-slate-200" :src="productImages[0]" mode="aspectFill" />
<view class="absolute bottom-3 right-3 rounded-full bg-slate-950/65 px-2 py-1 text-[10px] text-white">1 / {{ productImages.length }}</view>
<TicketMediaSwiper
:media-list="productImages"
class="h-full w-full bg-slate-200"
/>
</view>
<view v-else class="flex h-56 items-center justify-center bg-slate-200">
<text class="text-[12px] text-slate-400">暂无商品图片</text>
</view>
<view v-if="productImages.length > 1" class="flex gap-2 overflow-hidden bg-white px-4 pb-3 pt-2">
<image
v-for="(image, index) in productImages.slice(0, 4)"
:key="`${image}-${index}`"
class="h-11 w-16 rounded-lg object-cover"
:class="index === 0 ? 'ring-2 ring-blue-500' : 'opacity-70'"
:src="image"
mode="aspectFill"
/>
</view>
<view class="bg-white px-4 pb-4 pt-4">
<view class="flex flex-wrap gap-1.5">
<text v-if="product.fulfillmentLabel" class="rounded bg-blue-50 px-1.5 py-0.5 text-[10px] font-semibold text-blue-600">{{ product.fulfillmentLabel }}</text>
@@ -32,7 +23,7 @@
<template v-else>
<text class="pb-0.5 text-xs">{{ currencySymbol }}</text>
<text class="text-3xl font-bold leading-none">{{ product.startingPrice }}</text>
<text class="pb-0.5 text-[10px] text-slate-400">起</text>
<text class="pb-0.5 text-[10px] text-slate-400"></text>
</template>
</view>
</view>
@@ -52,7 +43,7 @@
<view class="flex items-center justify-between">
<view>
<text class="text-[12px] text-slate-500">优惠价</text>
<text class="ml-[4px] text-[14px] font-medium text-[#f26b32]">{{ currencySymbol }}<text class="text-[25px] font-bold">{{ product.startingPrice }}</text>起</text>
<text class="ml-[4px] text-[14px] font-medium text-[#f26b32]">{{ currencySymbol }}<text class="text-[25px] font-bold">{{ product.startingPrice }}</text></text>
</view>
<view class="rounded-full bg-[#f26b32] px-[28px] py-[11px]" @click="emit('buy', product.commodityId)">
<text class="text-[15px] font-semibold text-white">{{ product.bookingButtonText || '去预订' }}</text>
@@ -64,15 +55,23 @@
<script setup>
import { computed } from "vue";
import TicketMediaSwiper from "./TicketMediaSwiper.vue";
const props = defineProps({
product: { type: Object, required: true },
});
const emit = defineEmits(["buy"]);
const productImages = computed(() =>
[props.product.coverImage, ...(props.product.imageList || [])].filter(Boolean)
);
const productImages = computed(() => [
...new Set(
[
props.product.coverImage,
...(Array.isArray(props.product.imageList) ? props.product.imageList : []),
]
.filter((image) => typeof image === "string" && image.trim())
.map((image) => image.trim())
),
]);
const detailSections = computed(() =>
[...(props.product.detailSections || [])].sort(
(left, right) => Number(left.sortOrder || 0) - Number(right.sortOrder || 0)