feat(home): 重构首页轮播图组件并优化广告数据处理

- 修改首页轮播图组件,替换为新的 Banner 组件实现
- 新增广告图片数据标准化处理函数,支持多种字段格式兼容
- 优化首页广告数据加载逻辑,改用 Promise.allSettled 并行请求
- 修复轮播图高度计算,添加数字转换安全处理
- 调整经销商申请页面文本,将"入驻申请"改为"门店入驻"
- 修复商品卡片图片显示,添加空值处理防止报错
- 临时隐藏搜索栏组件,设置为隐藏状态
- 恢复开发环境 API 地址配置,便于本地调试
- 移除经销商申请表单中邀请人 ID 的禁用状态
This commit is contained in:
2026-01-20 11:12:31 +08:00
parent 0770eb1699
commit 0542b93dc7
6 changed files with 86 additions and 144 deletions

View File

@@ -6,13 +6,38 @@ import {Image} from '@nutui/nutui-react-taro'
import {getCmsAdByCode} from "@/api/cms/cmsAd";
import navTo from "@/utils/common";
import {pageCmsArticle} from "@/api/cms/cmsArticle";
import {CmsArticle} from "@/api/cms/cmsArticle/model";
type AdImage = {
url?: string
path?: string
title?: string
// Compatible keys (some backends use different fields)
src?: string
imageUrl?: string
}
function normalizeAdImages(ad?: CmsAd): AdImage[] {
const list = ad?.imageList
if (Array.isArray(list) && list.length) return list as AdImage[]
// Some APIs only return `images` as a JSON string.
const raw = ad?.images
if (!raw) return []
try {
const parsed = JSON.parse(raw)
return Array.isArray(parsed) ? (parsed as AdImage[]) : []
} catch {
return []
}
}
function toNumberPx(input: unknown, fallback: number) {
const n = typeof input === 'number' ? input : Number.parseInt(String(input ?? ''), 10)
return Number.isFinite(n) ? n : fallback
}
const MyPage = () => {
const [carouselData, setCarouselData] = useState<CmsAd>()
const [hotToday, setHotToday] = useState<CmsAd>()
const [item, setItem] = useState<CmsArticle>()
const [loading, setLoading] = useState(true)
// const [disableSwiper, setDisableSwiper] = useState(false)
@@ -21,24 +46,21 @@ const MyPage = () => {
// 加载数据
const loadData = async () => {
setLoading(true)
try {
setLoading(true)
// 轮播图
const flash = await getCmsAdByCode('flash')
// 今日热卖
const hotToday = await getCmsAdByCode('hot_today')
// 时里动态
const news = await pageCmsArticle({limit:1,recommend:1})
// 赋值
if(flash){
setCarouselData(flash)
}
if(hotToday){
setHotToday(hotToday)
}
if(news && news.list.length > 0){
setItem(news.list[0])
const [flashRes] = await Promise.allSettled([
getCmsAdByCode('flash'),
getCmsAdByCode('hot_today'),
pageCmsArticle({ limit: 1, recommend: 1 }),
])
if (flashRes.status === 'fulfilled') {
console.log('flashflashflash', flashRes.value)
setCarouselData(flashRes.value)
} else {
console.error('Failed to fetch flash:', flashRes.reason)
}
} catch (error) {
console.error('Banner数据加载失败:', error)
} finally {
@@ -47,11 +69,13 @@ const MyPage = () => {
}
useEffect(() => {
loadData()
loadData().then()
}, [])
// 轮播图高度默认300px
const carouselHeight = carouselData?.height || 300;
const carouselHeight = toNumberPx(carouselData?.height, 300)
const carouselImages = normalizeAdImages(carouselData)
console.log(carouselImages,'carouselImages')
// 骨架屏组件
const BannerSkeleton = () => (
@@ -100,94 +124,42 @@ const MyPage = () => {
}
return (
<View className="flex p-2 justify-between" style={{height: `${carouselHeight}px`}}>
{/* 左侧轮播图区域 */}
<View
style={{width: '50%', height: '100%'}}
className="banner-swiper-container"
>
<Swiper
defaultValue={0}
height={carouselHeight}
indicator
autoPlay
duration={3000}
style={{
height: `${carouselHeight}px`,
touchAction: 'pan-y' // 关键修改:允许垂直滑动
}}
disableTouch={false}
direction="horizontal"
className="custom-swiper"
>
{carouselData && carouselData?.imageList?.map((img, index) => (
<Swiper.Item key={index} style={{ touchAction: 'pan-x pan-y' }}>
<Image
width="100%"
height="100%"
src={img.url}
mode={'scaleToFill'}
onClick={() => navTo(`${img.path}`)}
lazyLoad={false}
style={{
height: `${carouselHeight}px`,
borderRadius: '4px',
touchAction: 'manipulation' // 关键修改:优化触摸操作
}}
/>
</Swiper.Item>
))}
</Swiper>
</View>
{/* 右侧上下图片区域 - 从API获取数据 */}
<View className="flex flex-col" style={{width: '50%', height: '100%'}}>
{/* 上层图片 - 使用今日热卖素材 */}
<View className={'ml-2 bg-white rounded-lg shadow-sm'}>
<View className={'px-3 my-2 font-bold text-sm'}></View>
<View className={'px-3 flex'} style={{
height: '110px'
}}>
{
hotToday?.imageList?.map(item => (
<View className={'item flex flex-col mr-1'} key={item.url}>
<Image
width={70}
height={70}
src={item.url}
mode={'scaleToFill'}
lazyLoad={false}
style={{
borderRadius: '4px'
}}
onClick={() => navTo('/shop/category/index?id=4424')}
/>
<View className={'text-xs py-2 text-orange-600 whitespace-nowrap'}>{item.title || '到手价¥9.9'}</View>
</View>
))
}
</View>
</View>
{/* 下层图片 - 使用社区拼团素材 */}
<View className={'ml-2 bg-white rounded-lg mt-3 shadow-sm'}>
<View className={'px-3 my-2 font-bold text-sm'}></View>
<View className={'rounded-lg px-3 pb-3'}>
<Swiper
defaultValue={0}
height={carouselHeight}
indicator
autoPlay
duration={3000}
style={{
height: `${carouselHeight}px`,
touchAction: 'pan-y' // 关键修改:允许垂直滑动
}}
disableTouch={false}
direction="horizontal"
className="custom-swiper"
>
{carouselImages.map((img, index) => {
const src = img.url || img.src || img.imageUrl
if (!src) return null
return (
<Swiper.Item key={index} style={{ touchAction: 'pan-x pan-y' }}>
<Image
width={'100%'}
height={94}
src={item?.image}
width="100%"
height="100%"
src={src}
mode={'scaleToFill'}
onClick={() => (img.path ? navTo(`${img.path}`) : undefined)}
lazyLoad={false}
style={{
borderRadius: '4px'
height: `${carouselHeight}px`,
borderRadius: '4px',
touchAction: 'manipulation' // 关键修改:优化触摸操作
}}
onClick={() => navTo('cms/detail/index?id=' + item?.articleId)}
/>
</View>
</View>
</View>
</View>
</Swiper.Item>
)
})}
</Swiper>
)
}