Browse Source

feat(Banner):重构 Banner 组件布局与数据逻辑

- 使用 `View` 替代 `div`,优化 Taro 组件结构
- 移除旧的广告位状态逻辑,引入商品数据接口 `listShopGoods`
- 调整右侧热卖区域展示结构,支持商品列表渲染
- 更新图片点击跳转路径及样式细节feat(BestSellers): 增加 Tabs 分类展示热销商品

- 引入 `Tabs` 组件实现分类切换功能- 当前仅实现“今日主推”Tab 展示商品列表
- 其他 Tab(即将到期、活动预告)暂显示空状态组件
-优化部分样式和 Swiper 高度设置

feat(UserCard): 设置用户头像默认图片及移除冗余属性

- 在未登录或无头像时显示默认头像
- 移除 `Image` 组件中冗余的 `alt` 属性

refactor(OrderList): 移除未使用的导航工具函数

- 删除从 `navigation` 工具中导入的 `switchTab` 函数引用
master
科技小王子 1 week ago
parent
commit
611f0e3216
  1. 118
      src/pages/index/Banner.tsx
  2. 55
      src/pages/index/BestSellers.tsx
  3. 5
      src/pages/user/components/UserCard.tsx
  4. 2
      src/user/order/components/OrderList.tsx

118
src/pages/index/Banner.tsx

@ -1,15 +1,19 @@
import {useEffect, useState} from 'react'
import {View} from '@tarojs/components'
import {Swiper} from '@nutui/nutui-react-taro'
import {CmsAd} from "@/api/cms/cmsAd/model";
import {Image} from '@nutui/nutui-react-taro'
import {getCmsAd} from "@/api/cms/cmsAd";
import navTo from "@/utils/common";
import {ShopGoods} from "@/api/shop/shopGoods/model";
import {listShopGoods} from "@/api/shop/shopGoods";
const MyPage = () => {
const [carouselData, setCarouselData] = useState<CmsAd>()
const [hotToday, setHotToday] = useState<CmsAd>()
const [groupBuy, setGroupBuy] = useState<CmsAd>()
// const [hotToday, setHotToday] = useState<CmsAd>()
// const [groupBuy, setGroupBuy] = useState<CmsAd>()
const [hotGoods, setHotGoods] = useState<ShopGoods[]>([])
// 加载数据
const loadData = () => {
@ -18,12 +22,16 @@ const MyPage = () => {
setCarouselData(data)
})
// 今日热卖素材(上层图片)
getCmsAd(444).then(data => {
setHotToday(data)
})
// getCmsAd(444).then(data => {
// setHotToday(data)
// })
// 社区拼团素材(下层图片)
getCmsAd(445).then(data => {
setGroupBuy(data)
// getCmsAd(445).then(data => {
// setGroupBuy(data)
// })
// 今日热卖
listShopGoods({categoryId: 4424, limit: 2}).then(data => {
setHotGoods(data)
})
}
@ -35,9 +43,9 @@ const MyPage = () => {
const carouselHeight = carouselData?.height || 200;
return (
<div className="flex flex-row w-full gap-2 p-2 box-sizing-border" style={{height: `${carouselHeight}px`}}>
<View className="flex p-2 justify-between" style={{height: `${carouselHeight}px`}}>
{/* 左侧轮播图区域 */}
<div className="flex-1" style={{height: '100%'}}>
<View style={{width: '50%', height: '100%'}}>
<Swiper
defaultValue={0}
height={carouselHeight}
@ -54,70 +62,60 @@ const MyPage = () => {
onClick={() => navTo(`${img.path}`)}
lazyLoad={false}
style={{height: `${carouselHeight}px`, borderRadius: '4px'}}
alt={`轮播图${index + 1}`}
/>
</Swiper.Item>
))}
</Swiper>
</div>
</View>
{/* 右侧上下图片区域 - 从API获取数据 */}
<div className="flex-1 flex flex-col gap-2" style={{height: '100%'}}>
<View className="flex flex-col" style={{width: '50%', height: '100%'}}>
{/* 上层图片 - 使用今日热卖素材 */}
<div style={{height: '50%'}}>
{hotToday?.imageList?.length ? (
<Image
width="100%"
height="100%"
src={hotToday.imageList[0].url}
mode={'scaleToFill'}
onClick={() => navTo("/cms/category/index?id=4424" || '')}
lazyLoad={false}
style={{borderRadius: '4px'}}
alt="今日热卖"
/>
) : (
<div style={{
height: '100%',
backgroundColor: '#f5f5f5',
borderRadius: '4px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}>
<span style={{color: '#999', fontSize: '12px'}}>...</span>
</div>
)}
</div>
<View className={'ml-2 bg-white rounded-lg'}>
<View className={'px-3 my-2 font-bold text-sm'}></View>
<View className={'px-3 flex'} style={{
height: '110px'
}}>
{
hotGoods.map(item => (
<View className={'item flex flex-col mr-4'}>
<Image
width={70}
height={70}
src={item.image}
mode={'scaleToFill'}
lazyLoad={false}
style={{
borderRadius: '4px'
}}
onClick={() => navTo('/shop/category/index?id=4424')}
/>
<View className={'text-xs py-2'}>¥{item.price}</View>
</View>
))
}
</View>
</View>
{/* 下层图片 - 使用社区拼团素材 */}
<div style={{height: '50%'}}>
{groupBuy?.imageList?.length ? (
<View className={'ml-2 bg-white rounded-lg mt-3'}>
<View className={'px-3 my-2 font-bold text-sm'}></View>
<View className={'rounded-lg px-3 pb-3'}>
<Image
width="100%"
height="100%"
src={groupBuy.imageList[0].url}
width={'100%'}
height={100}
src={'https://oss.wsdns.cn/20250919/941c99899e694a7798cab3bb28f1f238.png?x-oss-process=image/resize,m_fixed,w_750/quality,Q_90'}
mode={'scaleToFill'}
onClick={() => navTo(groupBuy.imageList[0].path || '')}
lazyLoad={false}
style={{borderRadius: '4px'}}
alt="社区拼团"
style={{
borderRadius: '4px'
}}
onClick={() => navTo('cms/detail/index?id=10109')}
/>
) : (
<div style={{
height: '100%',
backgroundColor: '#f5f5f5',
borderRadius: '4px',
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
}}>
<span style={{color: '#999', fontSize: '12px'}}>...</span>
</div>
)}
</div>
</div>
</div>
</View>
</View>
</View>
</View>
)
}

55
src/pages/index/BestSellers.tsx

@ -1,14 +1,15 @@
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 {useEffect, useState} from "react";
import {Image, Swiper, SwiperItem, Empty} 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 {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)
// 轮播图固定高度,可根据需求调整
@ -41,7 +42,7 @@ const BestSellers = () => {
}
}
// 返回新对象,避免直接修改原对象
return { ...item, pics };
return {...item, pics};
};
// 处理商品列表
@ -101,7 +102,26 @@ const BestSellers = () => {
return (
<View className={'py-3'}>
<View className={'flex flex-col justify-between items-center rounded-lg px-2'}>
{list?.map((item) => (
<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'}
@ -134,7 +154,7 @@ const BestSellers = () => {
</Swiper>
) : (
// 没有图片时显示占位图
<View className="no-image-placeholder" style={{ height: `${SWIPER_HEIGHT}px` }}>
<View className="no-image-placeholder" style={{height: `${SWIPER_HEIGHT}px`}}>
<Text className="placeholder-text"></Text>
</View>
)}
@ -161,7 +181,7 @@ const BestSellers = () => {
</View>
</View>
<Text
className={'text-white pl-4 pr-5'}
className={'text-white pl-5 pr-5'}
onClick={() => Taro.navigateTo({
url: `/shop/goodsDetail/index?id=${item.goodsId}`
})}
@ -174,6 +194,19 @@ const BestSellers = () => {
</View>
</View>
))}
{
tab1value == '1' && <Empty description="暂无相关商品" style={{
background: 'transparent',
}}/>
}
{
tab1value == '2' && <Empty description="暂无相关商品" style={{
background: 'transparent',
}}/>
}
</View>
</View>
)

5
src/pages/user/components/UserCard.tsx

@ -184,10 +184,10 @@ const UserCard = forwardRef<any, any>((_, ref) => {
<View className={'flex items-center mx-4'}>
{
IsLogin ? (
<Avatar size="large" src={userInfo?.avatar} shape="round"/>
<Avatar size="large" src={userInfo?.avatar || 'https://oss.wsdns.cn/20250623/62f830b85edb4a7293b8948c25e6f987.jpeg'} shape="round"/>
) : (
<Button className={'text-black'} open-type="getPhoneNumber" onGetPhoneNumber={handleGetPhoneNumber}>
<Avatar size="large" src={userInfo?.avatar} shape="round"/>
<Avatar size="large" src={userInfo?.avatar || 'https://oss.wsdns.cn/20250623/62f830b85edb4a7293b8948c25e6f987.jpeg'} shape="round"/>
</Button>
)
}
@ -240,7 +240,6 @@ const UserCard = forwardRef<any, any>((_, ref) => {
>
<Image
src="https://oss.wsdns.cn/20250913/7c3de38b377344b89131aba40214f63f.png"
alt="个人资料"
style={{
width:"200rpx"
}}

2
src/user/order/components/OrderList.tsx

@ -11,7 +11,7 @@ import {ShopOrderGoods} from "@/api/shop/shopOrderGoods/model";
import {copyText} from "@/utils/common";
import PaymentCountdown from "@/components/PaymentCountdown";
import {PaymentType} from "@/utils/payment";
import {goTo, switchTab} from "@/utils/navigation";
import {goTo} from "@/utils/navigation";
// 判断订单是否支付已过期
const isPaymentExpired = (createTime: string, timeoutHours: number = 24): boolean => {

Loading…
Cancel
Save