import React, { useState, useEffect, useCallback, useRef } from 'react' import { View, Text, ScrollView, Swiper, SwiperItem, Image } from '@tarojs/components' import Taro, { useDidShow } from '@tarojs/taro' import { useUser } from '@/hooks/useUser' import { useShare } from '@/hooks/useShare' import { useScrollHeight } from '@/hooks/useScrollHeight' import { useNewOrderDetector } from '@/hooks/useNewOrderDetector' import { useVipStatus } from '@/hooks/useVipStatus' import { getMyClerk } from '@/api/shop/shopStoreUser' import { pageShopOrder } from '@/api/shop/shopOrder' import { listCmsAd } from '@/api/cms/cmsAd' import { listCmsArticle } from '@/api/cms/cmsArticle' import { pageShopGoods } from '@/api/shop/shopGoods' import type { CmsAd } from '@/api/cms/cmsAd/model' import type { CmsArticle } from '@/api/cms/cmsArticle/model' import type { ShopGoods } from '@/api/shop/shopGoods/model' import Price from '@/components/common/Price' import { getCompressedImageUrl } from '@/utils/image' definePageConfig({ navigationBarTitleText: '首页', enableShareAppMessage: true, enableShareTimeline: true, }) const IndexPage: React.FC = () => { const { user, isLoggedIn } = useUser() const [banners, setBanners] = useState([]) const [announcements, setAnnouncements] = useState([]) const [hotProducts, setHotProducts] = useState([]) const [loading, setLoading] = useState(true) const scrollHeight = useScrollHeight(44) // VIP 状态:异步校验并更新缓存,isVip 变化时触发重渲染 const { isVip } = useVipStatus() // 首页分享:好友 + 朋友圈 + 复制链接(右上角三个按钮全亮) useShare({ title: '鑫龙家电 - 精选好物,实惠到家,等你来逛~', path: '/pages/index/index', enableTimeline: true, enableCopyUrl: true, }) // ─── 门店店员身份检测 ────────────────────────────────────────── const [isClerk, setIsClerk] = useState(false) const isClerkRef = useRef(false) // 登录后检查是否为门店店员 useEffect(() => { if (!isLoggedIn) { setIsClerk(false) isClerkRef.current = false return } getMyClerk() .then(data => { const clerk = !!data setIsClerk(clerk) isClerkRef.current = clerk }) .catch(() => { setIsClerk(false) isClerkRef.current = false }) }, [isLoggedIn]) // 页面重新显示时也刷新店员身份(可能从其他页面回来时状态变了) useDidShow(() => { if (isLoggedIn) { getMyClerk() .then(data => { const clerk = !!data setIsClerk(clerk) isClerkRef.current = clerk }) .catch(() => { isClerkRef.current = false }) } }) // ─── 新订单轮询检测(仅店员生效)──────────────────────────────── const { newOrderCount, clearUnread } = useNewOrderDetector({ interval: 30000, // 30 秒轮询一次 fetchLatestOrders: useCallback(() => { // 非店员不请求,返回空数组(baseline 不会建立,无副作用) if (!isClerkRef.current) return Promise.resolve([]) return pageShopOrder({ page: 1, limit: 5 }).then(r => r?.list || []) }, []), onNewOrders: useCallback((count) => { // 非门店店员不弹新订单提醒 if (!isClerkRef.current) return Taro.vibrateShort({ type: 'medium' }) Taro.showToast({ title: `您有 ${count} 条新订单`, icon: 'none', duration: 2500, }) }, []), }) const categories = ['全部', '球拍', '球鞋', '服装', '配件'] // 功能入口(8个) const featureEntries = [ { icon: '🎁', label: '全部商品', url: '/pages/shop/index' }, { icon: '🤝', label: '收货地址', url: '/pages/user/address-list' }, { icon: '🎫', label: '领券中心', url: '/pages/index/coupon-center/index' }, { icon: '⭐', label: '我的收藏', url: '/pages/user/favorite-list/index' }, { icon: '👑', label: '关于我们', url: '/pages/user/about/index' }, { icon: '💰', label: '积分商城', url: '/pages/points/index' }, { icon: '🏪', label: '门店信息', url: '/pages/store/list/index' }, { icon: '❓', label: '帮助中心', url: '/pages/user/help-center/index' }, ] // 获取轮播图 useEffect(() => { const fetchBanners = async () => { try { const data = await listCmsAd({ adType: 'banner', status: 0 }) setBanners(data || []) } catch (e) { console.error('获取轮播图失败:', e) } } const fetchAnnouncements = async () => { try { const data = await listCmsArticle({ category: 'notice', status: 1 }) setAnnouncements(data || []) } catch (e) { console.error('获取公告失败:', e) } finally { setLoading(false) } } fetchBanners() fetchAnnouncements() fetchHotProducts() }, []) // 获取热销商品 const fetchHotProducts = async () => { try { const res = await pageShopGoods({ page: 1, limit: 4, status: 0, recommend: 1 }) if (res?.list) { setHotProducts(res.list) } } catch (e) { console.error('获取热销商品失败:', e) } } const handleMessageClick = () => { if (!isLoggedIn) { Taro.navigateTo({ url: '/passport/login' }) return } // 店员 → 跳转门店订单管理页,有新订单时清除未读计数 if (isClerk) { if (newOrderCount > 0) clearUnread() Taro.navigateTo({ url: '/pages/store/orders/index' }) return } // 普通用户 → 跳消息通知页 Taro.navigateTo({ url: '/pages/index/notification' }) } /** * VIP 会员显示 dealerPrice(同时把 price 作为划线原价),非 VIP 维持原行为 */ const getHotDisplayPrice = (item: ShopGoods): { price: string; original?: string } => { if (isVip && item.dealerPrice) { return { price: item.dealerPrice, original: item.price } } const original = item.salePrice && item.salePrice !== item.price ? item.salePrice : undefined return { price: item.price || '0', original } } // tabBar 页面列表 const tabBarPages = ['/pages/index/index', '/pages/shop/index', '/pages/order/list', '/pages/user/user'] const handleFeatureClick = (url: string) => { if (tabBarPages.includes(url)) { Taro.switchTab({ url }) } else { Taro.navigateTo({ url }) } } return ( {/* 顶部搜索栏 */} Taro.navigateTo({ url: '/pages/index/search' })} > 🔍 搜索商品 🔔 {isClerk && newOrderCount > 0 && ( {newOrderCount > 99 ? '99+' : newOrderCount} )} {isClerk && newOrderCount === 0 && ( )} {/* 轮播图 */} {banners.length > 0 ? ( {banners.map(item => ( { if (item.path) Taro.navigateTo({ url: item.path }) }} /> ))} ) : ( 暂无轮播图 )} {/* 功能入口网格 */} {featureEntries.map(item => ( handleFeatureClick(item.url)} > {item.icon} {item.label} ))} {/* 公告栏 */} {announcements.length > 0 && ( 公告 {announcements.map(item => ( Taro.navigateTo({ url: `/pages/index/article-detail?id=${item.articleId}` })} > {item.title} ))} )} {/* 分类导航 */} 商品分类 {categories.map((item) => ( Taro.navigateTo({ url: '/pages/shop/category' })} > {item.slice(0, 1)} {item} ))} {/* 热销推荐 */} 热销推荐 Taro.switchTab({ url: '/pages/shop/index' })} > 查看更多 {'>'} {hotProducts.length > 0 ? ( hotProducts.map((item) => ( Taro.navigateTo({ url: `/pages/shop/product-detail?id=${item.goodsId}` })} > {item.image ? ( ) : ( 暂无图片 )} {item.goodsName || item.name} {isVip && item.dealerPrice ? ( VIP ) : null} {item.sales !== undefined && item.sales > 0 && ( 已售 {item.sales} )} )) ) : ( 暂无热销商品 )} ) } export default IndexPage