From 5ce0d76154bf4c1d70543476cdfad9a30195b0f8 Mon Sep 17 00:00:00 2001
From: shinnosuke <tantao@1hoper.com>
Date: 星期六, 10 十月 2026 16:44:38 +0800
Subject: [PATCH] fix(miniapp): 调整首页圆角布局并隐藏滚动条

---
 rencaika/pages/food-benefits/food-benefits.uvue |   49 ++++++++++++++++++++++++++++++++++++++++---------
 1 files changed, 40 insertions(+), 9 deletions(-)

diff --git a/rencaika/pages/food-benefits/food-benefits.uvue b/rencaika/pages/food-benefits/food-benefits.uvue
index c11b823..1b55d5e 100644
--- a/rencaika/pages/food-benefits/food-benefits.uvue
+++ b/rencaika/pages/food-benefits/food-benefits.uvue
@@ -10,9 +10,15 @@
 			</view>
 		</view>
 
-		<scroll-view class="page-scroll" scroll-y lower-threshold="80" @scroll="handlePageScroll" @scrolltolower="loadMoreMerchants">
+		<scroll-view :show-scrollbar="false" class="page-scroll" scroll-y lower-threshold="80" @scroll="handlePageScroll" @scrolltolower="loadMoreMerchants">
 			<view class="hero">
-				<image class="hero-image" :src="currentImage" mode="aspectFill" @error="replaceTopicImage"></image>
+				<!-- 主图跟着图册左右滑:滑动的主图与下方缩略图互相联动(点缩略图 = 主图滑过去)。 -->
+				<swiper v-if="gallery.length > 0" class="hero-swiper" :current="activeIndex < 0 ? 0 : activeIndex" :circular="gallery.length > 1" :duration="240" @change="handleHeroChange">
+					<swiper-item v-for="(item, index) in gallery" :key="item.id">
+						<image class="hero-image" :src="item.image" mode="aspectFill" @error="replaceGalleryImage(index)"></image>
+					</swiper-item>
+				</swiper>
+				<image v-else class="hero-image" :src="currentImage" mode="aspectFill" @error="replaceTopicImage"></image>
 				<view class="hero-top-shade"></view>
 				<view class="hero-bottom-shade"></view>
 
@@ -40,7 +46,8 @@
 						<image class="merchant-image" :src="item.image" mode="aspectFill" @error="replaceMerchantImage(item)"></image>
 						<view class="merchant-info">
 							<text class="merchant-name">{{item.name}}</text>
-							<view v-if="!item.available || item.hasCoupon || item.discount != ''" class="tag-row"><text v-if="item.hasCoupon" class="coupon-tag">券</text><text v-if="!item.available || item.discount != ''" class="discount-tag">{{item.available ? item.discount : '已下架'}}</text></view>
+							<view v-if="!item.available" class="tag-row"><text class="discount-tag">已下架</text></view>
+							<view v-else-if="item.tags.length > 0" class="tag-row"><text v-for="tag in item.tags" :key="tag" :class="tag == '券' ? 'coupon-tag' : 'discount-tag'">{{tag}}</text></view>
 							<view class="address-row"><image src="/static/benefits-assets/map-pin.svg"></image><text>{{item.address}}</text></view>
 						</view>
 					</view>
@@ -58,7 +65,7 @@
 	import { isApiConfigured } from '../../config/api.uts'
 	import { getFoodTopic, getFoodTopicMerchants } from '../../services/portal.uts'
 	import { resolveApiUrl } from '../../services/http.uts'
-	import { getSession } from '../../services/session.uts'
+	import { resolveTalentId } from '../../utils/talent-id.uts'
 	import { safeBack } from '../../utils/navigation.uts'
 
 	const navTop = ref(28)
@@ -69,7 +76,7 @@
 	const activeIndex = ref(-1)
 	const windowWidth = ref(375)
 	const thumbScrollLeft = ref(0)
-	const fallbackFoodImage = '/static/food-assets/food-1.jpg'
+	const fallbackFoodImage = '/static/common/image-placeholder.png'
 	const topicDescription = ref('')
 
 	const gallery = ref<any[]>([])
@@ -88,6 +95,20 @@
 	const currentPage = ref(0)
 	const listRequestVersion = ref(0)
 	const talentId = ref('')
+	const readListTags = (item: any, hasCoupon: boolean, discount: string): string[] => {
+		const tags: string[] = []
+		if (item != null && item.benefitTags instanceof Array) {
+			const records: any[] = item.benefitTags as any[]
+			for (let index = 0; index < records.length; index++) {
+				const tag = String(records[index]).trim()
+				if (tag != '' && tag != '人才专享' && tags.indexOf(tag) < 0) tags.push(tag)
+			}
+			return tags
+		}
+		if (hasCoupon) tags.push('券')
+		if (discount != '' && discount != '人才专享') tags.push(discount)
+		return tags
+	}
 
 	onLoad((options: any) => {
 		// #ifdef MP-WEIXIN
@@ -104,8 +125,7 @@
 			failInitialOnce.value = previewState == 'initialError'
 			failLoadMoreOnce.value = previewState == 'loadMoreError'
 		}
-		const session = getSession()
-		if (session != null && session.talentId != null) talentId.value = session.talentId as string
+		talentId.value = resolveTalentId()
 		loadFoodTopic()
 		loadInitialMerchants()
 	})
@@ -160,6 +180,12 @@
 		if (index >= gallery.value.length) index = gallery.value.length - 1
 		selectGallery(index)
 	}
+	/** 主图左右滑动:滑动落点同步到缩略图、菜名和描述卡。 */
+	const handleHeroChange = (event: any) => {
+		const current = event != null && event.detail != null && event.detail.current != null ? Number(event.detail.current) : -1
+		if (current < 0) return
+		selectGallery(current)
+	}
 	const handlePageScroll = (event: any) => {
 		const shouldShow = event.detail.scrollTop > 64
 		if (isSolidNav.value != shouldShow) isSolidNav.value = shouldShow
@@ -190,12 +216,15 @@
 			const next = append ? visibleMerchants.value.slice() : []
 			for (let index = 0; index < records.length; index++) {
 				const item = records[index]
+				const hasCoupon = item.couponAvailable === true || Number(item.couponAvailable) == 1
+				const discount = item.discountText != null && item.discountText != '人才专享' ? item.discountText as string : ''
 				next.push({
 					id: '' + item.id,
 					name: item.merchantName != null ? item.merchantName as string : '餐饮商户',
 					merchantType: item.merchantType != null ? item.merchantType as string : 'food',
-					discount: item.discountText != null && item.discountText != '人才专享' ? item.discountText as string : '',
-					hasCoupon: item.couponAvailable === true || Number(item.couponAvailable) == 1,
+					discount: discount,
+					hasCoupon: hasCoupon,
+					tags: readListTags(item, hasCoupon, discount),
 					address: item.address != null ? item.address as string : '',
 					image: item.coverUrl != null && item.coverUrl != '' ? resolveApiUrl(item.coverUrl as string) : fallbackFoodImage,
 					available: item.available !== false
@@ -248,6 +277,7 @@
 	.page { width: 100%; height: 100vh; background-color: #FFFFFF; }
 	.page-scroll { width: 100%; height: 100vh; background-color: #FFFFFF; }
 	.hero { height: 730rpx; position: relative; z-index: 2; overflow: visible; background-color: #332F29; }
+	.hero-swiper { position: absolute; left: 0; top: 0; width: 100%; height: 730rpx; }
 	.hero-image { position: absolute; left: 0; top: 0; width: 100%; height: 730rpx; }
 	.hero-top-shade { position: absolute; left: 0; right: 0; top: 0; height: 230rpx; background-image: linear-gradient(180deg, rgba(0,0,0,.62) 0%, rgba(0,0,0,.18) 65%, rgba(0,0,0,0) 100%); }
 	.hero-bottom-shade { position: absolute; left: 0; right: 0; bottom: 0; height: 230rpx; background-image: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(0,0,0,.45) 100%); }
@@ -286,6 +316,7 @@
 	.merchant-info { display: flex; min-width: 0; min-height: 184rpx; flex: 1; box-sizing: border-box; padding: 4rpx 0 4rpx 24rpx; flex-direction: column; justify-content: space-between; }
 	.merchant-name { color: #292929; font-size: 29rpx; line-height: 40rpx; font-weight: 700; }
 	.tag-row { display: flex; flex-direction: row; align-items: center; }
+	.tag-row text:first-child { margin-left: 0; }
 	.coupon-tag { padding: 6rpx 8rpx; border-radius: 6rpx; background-color: #FFF0EC; color: #FF5D37; font-size: 21rpx; }
 	.discount-tag { margin-left: 11rpx; padding: 6rpx 9rpx; border-radius: 6rpx; background-color: #FFF5E7; color: #FF7C2B; font-size: 21rpx; }
 	.address-row { display: flex; min-width: 0; box-sizing: border-box; padding: 7rpx 10rpx; border-radius: 7rpx; background-image: linear-gradient(90deg, rgba(239,240,242,.98) 0%, rgba(242,243,245,.76) 58%, rgba(255,255,255,0) 100%); flex-direction: row; align-items: flex-start; }

--
Gitblit v1.7.1