feat(user): 更新用户界面和功能实现- 默认 修改 UnifiedQRButton类型为 danger- 更新 Banner 组件使用 getCmsAdByCode 获取广告数据
- 新增 CMS 文章查询接口 getCmsArticleByCode - 调整 UserCard 组件界面样式和逻辑-优化 BestSellers 商品展示组件 - 更新 IsDealer 组件支持网站字段配置 - 移除用户页面部分冗余代码和样式 - 增加主题样式支持和背景装饰元素 - 调整用户相关组件层级和定位样式
This commit is contained in:
@@ -1,70 +1,37 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Image, Swiper, SwiperItem, Empty} from '@nutui/nutui-react-taro'
|
||||
import {Image} from '@nutui/nutui-react-taro'
|
||||
import {Share} from '@nutui/icons-react-taro'
|
||||
import {View, Text} from '@tarojs/components';
|
||||
import Taro from "@tarojs/taro";
|
||||
import {Tabs} from '@nutui/nutui-react-taro'
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {pageShopGoods} from "@/api/shop/shopGoods";
|
||||
|
||||
|
||||
const BestSellers = () => {
|
||||
const [tab1value, setTab1value] = useState<string | number>('0')
|
||||
const [list, setList] = useState<ShopGoods[]>([])
|
||||
const [goods, setGoods] = useState<ShopGoods | null>(null)
|
||||
// 轮播图固定高度,可根据需求调整
|
||||
const SWIPER_HEIGHT = 180;
|
||||
const [goods, setGoods] = useState<ShopGoods>()
|
||||
|
||||
const reload = () => {
|
||||
pageShopGoods({}).then(res => {
|
||||
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);
|
||||
});
|
||||
setList(res?.list || []);
|
||||
})
|
||||
}
|
||||
|
||||
// 处理分享点击
|
||||
const handleShare = (item: ShopGoods) => {
|
||||
setGoods(item);
|
||||
|
||||
console.log(goods)
|
||||
|
||||
// 显示分享选项菜单
|
||||
Taro.showActionSheet({
|
||||
itemList: ['分享给好友'],
|
||||
success: (res) => {
|
||||
if (res.tapIndex === 0) {
|
||||
// 分享给好友 - 触发转发
|
||||
Taro.showShareMenu({
|
||||
withShareTicket: true,
|
||||
success: () => {
|
||||
// 提示用户点击右上角分享
|
||||
Taro.showToast({
|
||||
title: '请点击右上角分享给好友',
|
||||
icon: 'none',
|
||||
@@ -81,135 +48,56 @@ const BestSellers = () => {
|
||||
}
|
||||
|
||||
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 (
|
||||
<View className={'py-3'}>
|
||||
<View className={'flex flex-col justify-between items-center rounded-lg px-2'}>
|
||||
<Tabs
|
||||
value={tab1value}
|
||||
className={'w-full'}
|
||||
onChange={(value) => {
|
||||
setTab1value(value)
|
||||
}}
|
||||
style={{
|
||||
backgroundColor: '#fff',
|
||||
}}
|
||||
activeType="smile"
|
||||
>
|
||||
<Tabs.TabPane title="今日主推">
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane title="即将到期">
|
||||
</Tabs.TabPane>
|
||||
<Tabs.TabPane title="活动预告">
|
||||
</Tabs.TabPane>
|
||||
</Tabs>
|
||||
|
||||
{tab1value == '0' && 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="12px 12px 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>
|
||||
<View className={'car-no text-sm'}>{item.name}</View>
|
||||
<View className={'flex justify-between text-xs py-1'}>
|
||||
<Text className={'text-orange-500'}>{item.comments}</Text>
|
||||
<Text className={'text-gray-400'}>已售 {item.sales}</Text>
|
||||
</View>
|
||||
<View className={'flex justify-between items-center py-2'}>
|
||||
<View className={'flex text-red-500 text-xl items-baseline'}>
|
||||
<Text className={'text-xs'}>¥</Text>
|
||||
<Text className={'font-bold text-2xl'}>{item.price}</Text>
|
||||
</View>
|
||||
<View className={'buy-btn'}>
|
||||
<View className={'cart-icon flex items-center hidden'}>
|
||||
<View
|
||||
className={'flex flex-col justify-center items-center text-white px-3 gap-1 text-nowrap whitespace-nowrap cursor-pointer'}
|
||||
onClick={() => handleShare(item)}
|
||||
>
|
||||
<Share size={20}/>
|
||||
<>
|
||||
<View className={'py-3'}>
|
||||
<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})}/>
|
||||
<View className={'flex flex-col p-2 rounded-lg'}>
|
||||
<View>
|
||||
<View className={'car-no text-sm'}>{item.name}</View>
|
||||
<View className={'flex justify-between text-xs py-1'}>
|
||||
<Text className={'text-orange-500'}>{item.comments}</Text>
|
||||
<Text className={'text-gray-400'}>已售 {item.sales}</Text>
|
||||
</View>
|
||||
<View className={'flex justify-between items-center py-2'}>
|
||||
<View className={'flex text-red-500 text-xl items-baseline'}>
|
||||
<Text className={'text-xs'}>¥</Text>
|
||||
<Text className={'font-bold text-2xl'}>{item.price}</Text>
|
||||
</View>
|
||||
<View className={'buy-btn'}>
|
||||
<View className={'cart-icon items-center hidden'}>
|
||||
<View
|
||||
className={'flex flex-col justify-center items-center text-white px-3 gap-1 text-nowrap whitespace-nowrap cursor-pointer'}
|
||||
onClick={() => handleShare(item)}
|
||||
>
|
||||
<Share size={20}/>
|
||||
</View>
|
||||
</View>
|
||||
<Text className={'text-white pl-4 pr-5'}
|
||||
onClick={() => Taro.navigateTo({url: '/shop/goodsDetail/index?id=' + item.goodsId})}>购买
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
<Text
|
||||
className={'text-white pl-5 pr-5'}
|
||||
onClick={() => Taro.navigateTo({
|
||||
url: `/shop/goodsDetail/index?id=${item.goodsId}`
|
||||
})}
|
||||
>
|
||||
购买
|
||||
</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
|
||||
{
|
||||
tab1value == '1' && <Empty description="暂无相关商品" style={{
|
||||
background: 'transparent',
|
||||
}}/>
|
||||
}
|
||||
|
||||
{
|
||||
tab1value == '2' && <Empty description="暂无相关商品" style={{
|
||||
background: 'transparent',
|
||||
}}/>
|
||||
}
|
||||
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default BestSellers
|
||||
|
||||
Reference in New Issue
Block a user