From 566b2cc4e0b668c67e8b8b4030b98066db000734 Mon Sep 17 00:00:00 2001 From: RyRh <3123294924@qq.com> Date: Mon, 24 Aug 2026 15:56:48 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=94=B9=E9=A2=9C=E8=89=B2=E8=BD=AE?= =?UTF-8?q?=E6=92=AD=E5=9B=BE=E6=94=B9=E5=8F=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/DetailSwiper.vue | 7 +++ pages/product-detail/product-detail.vue | 55 ++++++++++++++++--- 2 files changed, 55 insertions(+), 7 deletions(-) diff --git a/pages/product-detail/components/DetailSwiper.vue b/pages/product-detail/components/DetailSwiper.vue index e86db26..659547b 100644 --- a/pages/product-detail/components/DetailSwiper.vue +++ b/pages/product-detail/components/DetailSwiper.vue @@ -5,6 +5,7 @@ class="swiper" :circular="true" :indicator-dots="false" + :current="current" @change="onChange" > @@ -40,6 +41,12 @@ export default { current: 0 } }, + watch: { + images() { + // 切换图片数组时重置指示点到第一张 + this.current = 0 + } + }, methods: { onChange(e) { this.current = e.detail.current diff --git a/pages/product-detail/product-detail.vue b/pages/product-detail/product-detail.vue index e177ac4..b967ead 100644 --- a/pages/product-detail/product-detail.vue +++ b/pages/product-detail/product-detail.vue @@ -90,6 +90,10 @@ export default { sizeChart: {}, // 变体列表(来自接口 variants),用于校验尺码+颜色组合、获取价格、包装规格 variants: [], + // 按颜色分组的图片映射:{ [colorId]: [url, ...] }(来自 detail.mediaByColor) + mediaByColor: {}, + // 默认轮播图(无颜色或 mediaByColor 缺失时使用,来自 detail.media.images) + defaultImages: [], packaging: null } }, @@ -135,20 +139,24 @@ export default { ] } - // 2. 图片画廊:按 sortOrder 升序,首图置顶 + // 2. 图片画廊: + // - defaultImages:来自 detail.media.images(按 sortOrder 升序,首图置顶) + // - mediaByColor:来自 detail.mediaByColor,结构 [{ colorId, colorName, colorHex, images:[url,...] }] + // 顶部轮播优先显示选中颜色对应的图片;mediaByColor 缺失或当前颜色无图时回退到 defaultImages const media = detail.media || {} - let images = (media.images || []) + let defaultImages = (media.images || []) .slice() .sort((a, b) => (a.sortOrder || 0) - (b.sortOrder || 0)) .map((img) => img.url) .filter((url) => url) - if (media.primaryImageUrl && images.indexOf(media.primaryImageUrl) === -1) { - images.unshift(media.primaryImageUrl) + if (media.primaryImageUrl && defaultImages.indexOf(media.primaryImageUrl) === -1) { + defaultImages.unshift(media.primaryImageUrl) } - if (!images.length && detail.image) { - images.push(detail.image) + if (!defaultImages.length && detail.image) { + defaultImages.push(detail.image) } - this.productImages = images + this.defaultImages = defaultImages + this.mediaByColor = this.buildMediaByColor(detail.mediaByColor) // 3. 颜色:仅取启用项,按 sortOrder 升序 const colors = ((detail.options && detail.options.colors) || []) @@ -182,6 +190,38 @@ export default { // 9. 初始价格(按默认选中的 尺码+颜色 匹配变体价格) this.syncPriceByVariant() + + // 10. 初始轮播图(按默认选中颜色取 mediaByColor,无则回退 defaultImages) + this.syncImagesByColor() + }, + + /** + * 将接口 mediaByColor 数组转为 colorId -> [url] 映射 + * 入参:[{ colorId, colorName, colorHex, images:[url,...] }] + * 出参:{ '1126198': [url, ...], ... } + */ + buildMediaByColor(list) { + const map = {} + if (Array.isArray(list)) { + list.forEach((item) => { + if (!item || item.colorId == null) return + const imgs = Array.isArray(item.images) ? item.images.filter((u) => u) : [] + if (imgs.length) map[String(item.colorId)] = imgs + }) + } + return map + }, + + /** + * 按当前 selectedColorId 同步顶部轮播图: + * - 若 mediaByColor 命中且该颜色有图,则使用该颜色的图片数组 + * - 否则回退到 defaultImages + */ + syncImagesByColor() { + const colorId = this.selectedColorId + const byColor = this.mediaByColor || {} + const imgs = colorId && byColor[String(colorId)] ? byColor[String(colorId)] : this.defaultImages + this.productImages = (imgs || []).slice() }, /** @@ -338,6 +378,7 @@ export default { */ selectColor(id) { this.selectedColorId = id + this.syncImagesByColor() this.syncPriceByVariant() }, /**