|
@ -1,21 +1,55 @@ |
|
|
import {useEffect, useState} from "react"; |
|
|
|
|
|
import {Image} from '@nutui/nutui-react-taro' |
|
|
|
|
|
import {Share} from '@nutui/icons-react-taro' |
|
|
|
|
|
import {View, Text} from '@tarojs/components'; |
|
|
|
|
|
import Taro, {useShareAppMessage} from "@tarojs/taro"; |
|
|
|
|
|
import {ShopGoods} from "@/api/shop/shopGoods/model"; |
|
|
|
|
|
import {pageShopGoods} from "@/api/shop/shopGoods"; |
|
|
|
|
|
|
|
|
import { useEffect, useState } from "react"; |
|
|
|
|
|
import { Image, Swiper, SwiperItem } from '@nutui/nutui-react-taro' |
|
|
|
|
|
import { Share } from '@nutui/icons-react-taro' |
|
|
|
|
|
import { View, Text } from '@tarojs/components'; |
|
|
|
|
|
import Taro from "@tarojs/taro"; |
|
|
|
|
|
import { ShopGoods } from "@/api/shop/shopGoods/model"; |
|
|
|
|
|
import { pageShopGoods } from "@/api/shop/shopGoods"; |
|
|
import './BestSellers.scss' |
|
|
import './BestSellers.scss' |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const BestSellers = () => { |
|
|
const BestSellers = () => { |
|
|
const [list, setList] = useState<ShopGoods[]>([]) |
|
|
const [list, setList] = useState<ShopGoods[]>([]) |
|
|
const [goods, setGoods] = useState<ShopGoods>() |
|
|
|
|
|
|
|
|
const [goods, setGoods] = useState<ShopGoods | null>(null) |
|
|
|
|
|
// 轮播图固定高度,可根据需求调整
|
|
|
|
|
|
const SWIPER_HEIGHT = 180; |
|
|
|
|
|
|
|
|
const reload = () => { |
|
|
const reload = () => { |
|
|
pageShopGoods({}).then(res => { |
|
|
pageShopGoods({}).then(res => { |
|
|
setList(res?.list || []); |
|
|
|
|
|
}) |
|
|
|
|
|
|
|
|
const processGoodsItem = (item: ShopGoods) => { |
|
|
|
|
|
const pics: string[] = []; |
|
|
|
|
|
// 添加主图
|
|
|
|
|
|
if (item.image) { |
|
|
|
|
|
pics.push(item.image); |
|
|
|
|
|
} |
|
|
|
|
|
// 处理附加图片
|
|
|
|
|
|
if (item.files) { |
|
|
|
|
|
try { |
|
|
|
|
|
// 解析文件字符串为对象
|
|
|
|
|
|
const files = typeof item.files === "string" |
|
|
|
|
|
? JSON.parse(item.files) |
|
|
|
|
|
: item.files; |
|
|
|
|
|
|
|
|
|
|
|
// 收集所有图片URL
|
|
|
|
|
|
Object.values(files).forEach(file => { |
|
|
|
|
|
if (file?.url) { |
|
|
|
|
|
pics.push(file.url); |
|
|
|
|
|
} |
|
|
|
|
|
}); |
|
|
|
|
|
} catch (error) { |
|
|
|
|
|
console.error('解析文件失败:', error); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
// 返回新对象,避免直接修改原对象
|
|
|
|
|
|
return { ...item, pics }; |
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// 处理商品列表
|
|
|
|
|
|
const goods = (res?.list || []).map(processGoodsItem); |
|
|
|
|
|
setList(goods); |
|
|
|
|
|
}).catch(err => { |
|
|
|
|
|
console.error('获取商品列表失败:', err); |
|
|
|
|
|
}); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
// 处理分享点击
|
|
|
// 处理分享点击
|
|
@ -27,11 +61,9 @@ const BestSellers = () => { |
|
|
itemList: ['分享给好友'], |
|
|
itemList: ['分享给好友'], |
|
|
success: (res) => { |
|
|
success: (res) => { |
|
|
if (res.tapIndex === 0) { |
|
|
if (res.tapIndex === 0) { |
|
|
// 分享给好友 - 触发转发
|
|
|
|
|
|
Taro.showShareMenu({ |
|
|
Taro.showShareMenu({ |
|
|
withShareTicket: true, |
|
|
withShareTicket: true, |
|
|
success: () => { |
|
|
success: () => { |
|
|
// 提示用户点击右上角分享
|
|
|
|
|
|
Taro.showToast({ |
|
|
Taro.showToast({ |
|
|
title: '请点击右上角分享给好友', |
|
|
title: '请点击右上角分享给好友', |
|
|
icon: 'none', |
|
|
icon: 'none', |
|
@ -48,22 +80,65 @@ const BestSellers = () => { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
|
reload() |
|
|
|
|
|
}, []) |
|
|
|
|
|
|
|
|
reload(); |
|
|
|
|
|
}, []); |
|
|
|
|
|
|
|
|
// 注意:不在这里配置分享,避免与首页分享冲突
|
|
|
|
|
|
// 商品分享应该在商品详情页处理,首页分享应该分享首页本身
|
|
|
|
|
|
|
|
|
// 配置分享内容
|
|
|
|
|
|
Taro.useShareAppMessage(() => { |
|
|
|
|
|
if (goods) { |
|
|
|
|
|
return { |
|
|
|
|
|
title: goods.name, |
|
|
|
|
|
path: `/shop/goodsDetail/index?id=${goods.goodsId}`, |
|
|
|
|
|
imageUrl: goods.image || '' |
|
|
|
|
|
}; |
|
|
|
|
|
} |
|
|
|
|
|
return { |
|
|
|
|
|
title: '热销商品', |
|
|
|
|
|
path: '/pages/index/index' |
|
|
|
|
|
}; |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
return ( |
|
|
return ( |
|
|
<> |
|
|
|
|
|
<View className={'py-3'}> |
|
|
<View className={'py-3'}> |
|
|
<View className={'flex flex-col justify-between items-center rounded-lg px-2'}> |
|
|
<View className={'flex flex-col justify-between items-center rounded-lg px-2'}> |
|
|
{list?.map((item, index) => { |
|
|
|
|
|
return ( |
|
|
|
|
|
<View key={index} className={'flex flex-col rounded-lg bg-white shadow-sm w-full mb-5'}> |
|
|
|
|
|
<Image src={item.image} mode={'aspectFit'} lazyLoad={false} |
|
|
|
|
|
radius="10px 10px 0 0" height="180" |
|
|
|
|
|
onClick={() => Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}/> |
|
|
|
|
|
|
|
|
{list?.map((item) => ( |
|
|
|
|
|
<View |
|
|
|
|
|
key={item.goodsId || item.id} // 使用商品唯一ID作为key
|
|
|
|
|
|
className={'flex flex-col rounded-lg bg-white shadow-sm w-full mb-5'} |
|
|
|
|
|
> |
|
|
|
|
|
{/* 轮播图组件 */} |
|
|
|
|
|
{item.pics && item.pics.length > 0 ? ( |
|
|
|
|
|
<Swiper |
|
|
|
|
|
defaultValue={0} |
|
|
|
|
|
height={SWIPER_HEIGHT} |
|
|
|
|
|
indicator |
|
|
|
|
|
className="swiper-container" |
|
|
|
|
|
autoPlay |
|
|
|
|
|
interval={3000} |
|
|
|
|
|
> |
|
|
|
|
|
{item.pics.map((pic, picIndex) => ( |
|
|
|
|
|
<SwiperItem key={picIndex}> |
|
|
|
|
|
<Image |
|
|
|
|
|
radius="10px 10px 0 0" |
|
|
|
|
|
height={SWIPER_HEIGHT} |
|
|
|
|
|
src={pic} |
|
|
|
|
|
mode={'aspectFill'} // 使用aspectFill保持比例并填充容器
|
|
|
|
|
|
lazyLoad |
|
|
|
|
|
onClick={() => Taro.navigateTo({ |
|
|
|
|
|
url: `/shop/goodsDetail/index?id=${item.goodsId}` |
|
|
|
|
|
})} |
|
|
|
|
|
className="swiper-image" |
|
|
|
|
|
/> |
|
|
|
|
|
</SwiperItem> |
|
|
|
|
|
))} |
|
|
|
|
|
</Swiper> |
|
|
|
|
|
) : ( |
|
|
|
|
|
// 没有图片时显示占位图
|
|
|
|
|
|
<View className="no-image-placeholder" style={{ height: `${SWIPER_HEIGHT}px` }}> |
|
|
|
|
|
<Text className="placeholder-text">暂无图片</Text> |
|
|
|
|
|
</View> |
|
|
|
|
|
)} |
|
|
|
|
|
|
|
|
<View className={'flex flex-col p-2 rounded-lg'}> |
|
|
<View className={'flex flex-col p-2 rounded-lg'}> |
|
|
<View> |
|
|
<View> |
|
|
<View className={'car-no text-sm'}>{item.name}</View> |
|
|
<View className={'car-no text-sm'}>{item.name}</View> |
|
@ -85,19 +160,23 @@ const BestSellers = () => { |
|
|
<Share size={20}/> |
|
|
<Share size={20}/> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
<Text className={'text-white pl-4 pr-5'} |
|
|
|
|
|
onClick={() => Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}>购买 |
|
|
|
|
|
|
|
|
<Text |
|
|
|
|
|
className={'text-white pl-4 pr-5'} |
|
|
|
|
|
onClick={() => Taro.navigateTo({ |
|
|
|
|
|
url: `/shop/goodsDetail/index?id=${item.goodsId}` |
|
|
|
|
|
})} |
|
|
|
|
|
> |
|
|
|
|
|
购买 |
|
|
</Text> |
|
|
</Text> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
) |
|
|
|
|
|
})} |
|
|
|
|
|
|
|
|
))} |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</View> |
|
|
</> |
|
|
|
|
|
) |
|
|
) |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
export default BestSellers |
|
|
export default BestSellers |
|
|