feat(home): 重构首页界面并更新API配置
- 移除底部导航栏中的"基地生活"选项卡 - 切换开发环境API地址为线上测试接口 - 添加完整的首页样式定义,包括英雄区域、商品卡片、快捷入口等 - 重构首页组件结构,集成商品列表、分类标签页和交互功能 - 更新主题管理逻辑,支持多种主题模式和用户ID兼容处理 - 添加商品数据获取和展示功能,实现首页内容动态加载
This commit is contained in:
@@ -1,19 +1,17 @@
|
||||
import Header from './Header';
|
||||
import BestSellers from './BestSellers';
|
||||
import Taro from '@tarojs/taro';
|
||||
import {useShareAppMessage} from "@tarojs/taro"
|
||||
import {useEffect, useState} from "react";
|
||||
import {getShopInfo} from "@/api/layout";
|
||||
import Menu from "./Menu";
|
||||
import Banner from "./Banner";
|
||||
import {checkAndHandleInviteRelation, hasPendingInvite} from "@/utils/invite";
|
||||
import Header from './Header'
|
||||
import Taro, { useShareAppMessage } from '@tarojs/taro'
|
||||
import { View, Text, Image, ScrollView } from '@tarojs/components'
|
||||
import { useEffect, useMemo, useState, type ReactNode } from 'react'
|
||||
import { Cart, Coupon, Gift, Ticket } from '@nutui/icons-react-taro'
|
||||
import { getShopInfo } from '@/api/layout'
|
||||
import { checkAndHandleInviteRelation, hasPendingInvite } from '@/utils/invite'
|
||||
import { pageShopGoods } from '@/api/shop/shopGoods'
|
||||
import type { ShopGoods } from '@/api/shop/shopGoods/model'
|
||||
import './index.scss'
|
||||
|
||||
function Home() {
|
||||
// 吸顶状态
|
||||
// const [stickyStatus, setStickyStatus] = useState<boolean>(false)
|
||||
// Tabs粘性状态
|
||||
const [_, setTabsStickyStatus] = useState<boolean>(false)
|
||||
const [activeTab, setActiveTab] = useState('推荐')
|
||||
const [goodsList, setGoodsList] = useState<ShopGoods[]>([])
|
||||
|
||||
useShareAppMessage(() => {
|
||||
// 获取当前用户ID,用于生成邀请链接
|
||||
@@ -85,9 +83,7 @@ function Home() {
|
||||
// }
|
||||
|
||||
// 处理Tabs粘性状态变化
|
||||
const handleTabsStickyChange = (isSticky: boolean) => {
|
||||
setTabsStickyStatus(isSticky)
|
||||
}
|
||||
// const handleTabsStickyChange = (isSticky: boolean) => {}
|
||||
|
||||
const reload = () => {
|
||||
|
||||
@@ -99,6 +95,10 @@ function Home() {
|
||||
|
||||
})
|
||||
|
||||
pageShopGoods({}).then(res => {
|
||||
setGoodsList(res?.list || [])
|
||||
})
|
||||
|
||||
// 检查是否有待处理的邀请关系 - 异步处理,不阻塞页面加载
|
||||
if (hasPendingInvite()) {
|
||||
console.log('检测到待处理的邀请关系')
|
||||
@@ -152,16 +152,177 @@ function Home() {
|
||||
});
|
||||
}, []);
|
||||
|
||||
const tabs = useMemo(() => ['推荐', '桶装水', '优惠组合', '购机套餐', '饮水设备'], [])
|
||||
|
||||
const shortcuts = useMemo<
|
||||
Array<{ key: string; title: string; icon: ReactNode; onClick: () => void }>
|
||||
>(
|
||||
() => [
|
||||
{
|
||||
key: 'ticket',
|
||||
title: '充值水票',
|
||||
icon: <Ticket size={30} />,
|
||||
onClick: () => Taro.navigateTo({ url: '/user/wallet/wallet' }),
|
||||
},
|
||||
{
|
||||
key: 'order',
|
||||
title: '立即订水',
|
||||
icon: <Cart size={30} />,
|
||||
onClick: () => Taro.switchTab({ url: '/pages/category/index' }),
|
||||
},
|
||||
{
|
||||
key: 'invite',
|
||||
title: '邀请有礼',
|
||||
icon: <Gift size={30} />,
|
||||
onClick: () => Taro.navigateTo({ url: '/dealer/qrcode/index' }),
|
||||
},
|
||||
{
|
||||
key: 'coupon',
|
||||
title: '领券中心',
|
||||
icon: <Coupon size={30} />,
|
||||
onClick: () => Taro.navigateTo({ url: '/coupon/index' }),
|
||||
},
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
const visibleGoods = useMemo(() => {
|
||||
// 先按效果图展示两列卡片,数据不够时也保持布局稳定
|
||||
const list = goodsList || []
|
||||
if (list.length <= 6) return list
|
||||
return list.slice(0, 6)
|
||||
}, [goodsList])
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* Header区域 - 现在由Header组件内部处理吸顶逻辑 */}
|
||||
<Header />
|
||||
|
||||
<div className={'flex flex-col mt-12'}>
|
||||
<Menu/>
|
||||
<Banner/>
|
||||
<BestSellers onStickyChange={handleTabsStickyChange}/>
|
||||
</div>
|
||||
<View className="home-page">
|
||||
{/* 顶部活动主视觉 */}
|
||||
<View className="home-hero">
|
||||
<View className="home-hero__bg" />
|
||||
<View className="home-hero__content">
|
||||
<View className="home-hero__left">
|
||||
<View className="home-hero__topRow">
|
||||
<View className="home-hero__brand">
|
||||
<Text className="home-hero__brandText">桂乐淘</Text>
|
||||
</View>
|
||||
<View className="home-hero__tag">
|
||||
<Text className="home-hero__tagText">新人有礼</Text>
|
||||
</View>
|
||||
<View className="home-hero__date">
|
||||
<Text className="home-hero__dateText">202X年X月X日 - X月X日</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="home-hero__headline">
|
||||
<Text className="home-hero__headlineText">大容量家庭装</Text>
|
||||
<Text className="home-hero__headlineText">净含量15L</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="home-hero__right">
|
||||
<View className="home-hero__bottle">
|
||||
<View className="home-hero__bottleCap" />
|
||||
<View className="home-hero__bottleLabel">
|
||||
<Text className="home-hero__bottleLabelText">山泉水</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 电子水票 */}
|
||||
<View className="ticket-card">
|
||||
<View className="ticket-card__head">
|
||||
<Text className="ticket-card__title">电子水票</Text>
|
||||
<Text className="ticket-card__count">
|
||||
您还有 <Text className="ticket-card__countNum">0</Text> 张水票
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<View className="ticket-card__body">
|
||||
<View className="shortcut-grid">
|
||||
{shortcuts.map((item) => (
|
||||
<View
|
||||
key={item.key}
|
||||
className="shortcut-grid__item"
|
||||
onClick={item.onClick}
|
||||
>
|
||||
<View className="shortcut-grid__icon">{item.icon}</View>
|
||||
<Text className="shortcut-grid__text">{item.title}</Text>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* 分类Tabs */}
|
||||
<ScrollView className="home-tabs" scrollX enableFlex>
|
||||
<View className="home-tabs__inner">
|
||||
{tabs.map((tab) => {
|
||||
const active = tab === activeTab
|
||||
return (
|
||||
<View
|
||||
key={tab}
|
||||
className={`home-tabs__item ${active ? 'home-tabs__item--active' : ''}`}
|
||||
onClick={() => setActiveTab(tab)}
|
||||
>
|
||||
<Text className="home-tabs__itemText">{tab}</Text>
|
||||
</View>
|
||||
)
|
||||
})}
|
||||
</View>
|
||||
</ScrollView>
|
||||
|
||||
{/* 商品列表 */}
|
||||
<View className="goods-grid">
|
||||
{visibleGoods.map((item) => (
|
||||
<View key={item.goodsId} className="goods-card">
|
||||
<View className="goods-card__imgWrap">
|
||||
<Image
|
||||
className="goods-card__img"
|
||||
src={item.image}
|
||||
mode="aspectFill"
|
||||
lazyLoad={false}
|
||||
onClick={() =>
|
||||
Taro.navigateTo({ url: `/shop/goodsDetail/index?id=${item.goodsId}` })
|
||||
}
|
||||
/>
|
||||
</View>
|
||||
|
||||
<View className="goods-card__body">
|
||||
<Text className="goods-card__title">{item.name}</Text>
|
||||
<View className="goods-card__meta">
|
||||
<Text className="goods-card__sold">已购:{item.sales || 0}人</Text>
|
||||
<View className="goods-card__price">
|
||||
<Text className="goods-card__priceUnit">¥</Text>
|
||||
<Text className="goods-card__priceValue">{item.price}</Text>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
<View className="goods-card__actions">
|
||||
<View
|
||||
className="goods-card__btn goods-card__btn--ghost"
|
||||
onClick={() => Taro.navigateTo({ url: '/user/coupon/index' })}
|
||||
>
|
||||
<Text className="goods-card__btnText">买水票更优惠</Text>
|
||||
</View>
|
||||
<View
|
||||
className="goods-card__btn goods-card__btn--primary"
|
||||
onClick={() =>
|
||||
Taro.navigateTo({ url: `/shop/goodsDetail/index?id=${item.goodsId}` })
|
||||
}
|
||||
>
|
||||
<Text className="goods-card__btnText goods-card__btnText--primary">立即购买</Text>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user