商品以及商品详情

This commit is contained in:
liu
2026-07-06 11:32:58 +08:00
parent 97e7a6083c
commit c25cf0e8b3
32 changed files with 3585 additions and 45 deletions
+126 -29
View File
@@ -1,10 +1,14 @@
import { useState, useMemo } from 'react'
import Taro from '@tarojs/taro'
import { View, ScrollView } from '@tarojs/components'
import { View, Text, ScrollView } from '@tarojs/components'
import { Search, Swiper, SwiperItem, Grid, GridItem, Tabs, Tab, Image as VantImage } from '@antmjs/vantui'
import ArticleCard from '@/components/ArticleCard'
import ProductCard from '@/components/ProductCard'
import { banners, navItems, articles } from '@/mock/articles'
import { products } from '@/mock/products'
import type { ArticleCategory } from '@/types/article'
import type { ProductCategory } from '@/types/product'
import type { Product } from '@/types/product'
import CustomTabBar from "@/custom-tab-bar";
import './index.less'
@@ -21,22 +25,45 @@ function getNavBarHeight() {
}
}
/** 分类标签映射 */
const TAB_LIST = [
{ title: '最新', value: 'latest' as ArticleCategory },
{ title: '推荐', value: 'recommend' as ArticleCategory },
{ title: '热点', value: 'hot' as ArticleCategory },
/** 统一板块标签:校园商城 + 文章分类 */
const MAIN_TABS = [
{ title: '校园商城', value: 'mall' },
{ title: '最新', value: 'latest' },
{ title: '推荐', value: 'recommend' },
{ title: '热点', value: 'hot' },
]
/** 商品分类标签 */
const PRODUCT_CATEGORIES: { title: string; value: ProductCategory | 'all' }[] = [
{ title: '全部', value: 'all' },
{ title: '数码', value: 'digital' },
{ title: '图书', value: 'book' },
{ title: '生活', value: 'life' },
{ title: '美食', value: 'food' },
{ title: '服饰', value: 'cloth' },
]
export default function Index() {
const [activeTab, setActiveTab] = useState(0)
const [activeMainTab, setActiveMainTab] = useState(0)
const [activeCategory, setActiveCategory] = useState(0)
const navBarHeight = useMemo(() => getNavBarHeight(), [])
/** 根据当前 tab 筛选文章 */
/** 当前选中的板块 */
const currentTab = MAIN_TABS[activeMainTab]?.value || 'mall'
/** 根据文章分类筛 */
const filteredArticles = useMemo(() => {
const category = TAB_LIST[activeTab]?.value || 'latest'
return articles.filter((a) => a.category === category)
}, [activeTab])
const value = MAIN_TABS[activeMainTab]?.value || 'latest'
if (value === 'mall') return articles.filter((a) => a.category === 'latest')
return articles.filter((a) => a.category === value)
}, [activeMainTab])
/** 根据当前分类筛选商品 */
const filteredProducts = useMemo(() => {
const catValue = PRODUCT_CATEGORIES[activeCategory]?.value || 'all'
if (catValue === 'all') return products
return products.filter((p) => p.category === catValue)
}, [activeCategory])
/** 搜索 */
const handleSearch = () => {
@@ -57,6 +84,21 @@ export default function Index() {
Taro.navigateTo({ url: `/pages/article/index?id=${id}` })
}
/** 商品点击 */
const handleProductClick = (product: Product) => {
Taro.navigateTo({ url: `/pages/product-detail/index?id=${product.id}` })
}
/** 查看全部商品 */
const handleViewAll = () => {
Taro.showToast({ title: '商城即将上线', icon: 'none' })
}
/** 商家入驻 */
const handleMerchantJoin = () => {
Taro.showToast({ title: '商家入驻即将上线', icon: 'none' })
}
return (
<View className='home-page'>
{/* ========== 自定义导航栏 (毛玻璃) ========== */}
@@ -128,36 +170,91 @@ export default function Index() {
</Grid>
</View>
{/* ========== 文章标签导航 (最新 / 推荐 / 热点) ========== */}
<View className='tabs-section'>
{/* ========== 统一板块:校园商城 | 最新 | 推荐 | 热点 ========== */}
<View className='main-tabs-section'>
<Tabs
active={activeTab}
onChange={(e) => setActiveTab(e.detail.index)}
active={activeMainTab}
onChange={(e) => setActiveMainTab(e.detail.index)}
sticky
offsetTop={navBarHeight.totalHeight}
color='#1989fa'
titleActiveColor='#1989fa'
titleInactiveColor='#646566'
animated
swipeable
>
{TAB_LIST.map((tab) => (
{MAIN_TABS.map((tab) => (
<Tab key={tab.value} title={tab.title} />
))}
</Tabs>
</View>
{/* ========== 文章列表 ========== */}
<View className='article-list'>
{filteredArticles.map((article) => (
<View
key={article.id}
className='article-item'
onClick={() => handleArticleClick(article.id)}
>
<ArticleCard article={article} />
{/* ===== 校园商城内容 ===== */}
{currentTab === 'mall' && (
<View className='mall-content'>
{/* 商品分类标签 */}
<ScrollView
className='category-scroll'
scrollX
enhanced
showScrollbar={false}
>
<View className='category-tabs'>
{PRODUCT_CATEGORIES.map((cat, idx) => (
<View
key={cat.value}
className={`category-tab ${activeCategory === idx ? 'active' : ''}`}
onClick={() => setActiveCategory(idx)}
>
<Text className='category-text'>{cat.title}</Text>
</View>
))}
</View>
</ScrollView>
{/* 商品双列网格 */}
<View className='product-grid'>
{filteredProducts.map((product) => (
<ProductCard
key={product.id}
product={product}
onClick={handleProductClick}
/>
))}
{filteredProducts.length === 0 && (
<View className='empty-grid'></View>
)}
</View>
{/* 商家入驻入口 */}
<View className='merchant-join-card' onClick={handleMerchantJoin}>
<View className='join-content'>
<Text className='join-icon'>🏪</Text>
<View className='join-text-wrap'>
<Text className='join-title'></Text>
<Text className='join-desc'></Text>
</View>
</View>
<Text className='join-arrow'></Text>
</View>
</View>
)}
{/* ===== 文章列表内容 ===== */}
{currentTab !== 'mall' && (
<View className='article-content'>
{filteredArticles.map((article) => (
<View
key={article.id}
className='article-item'
onClick={() => handleArticleClick(article.id)}
>
<ArticleCard article={article} />
</View>
))}
{filteredArticles.length === 0 && (
<View className='empty-tip'></View>
)}
</View>
))}
{filteredArticles.length === 0 && (
<View className='empty-tip'></View>
)}
</View>