import React, { useEffect, useState, useRef, useImperativeHandle } from 'react' import { useSelector, useDispatch } from 'react-redux' import Taro, { useDidShow, usePageScroll, getCurrentInstance, useReady } from '@tarojs/taro' import { View, Text, Image } from '@tarojs/components' import { useImmer } from 'use-immer' import { SpNavBar, SpFloatMenuItem, SpNote, SpLoading, SpImage, SpChat } from '@/components' import { TABBAR_PATH } from '@/consts' import { classNames, styleNames, hasNavbar, isWeixin, isAlipay, isGoodsShelves, entryLaunch, isObject } from '@/utils' import { AtBadge } from 'taro-ui' import './index.scss' const initialState = { lock: false, lockStyle: {}, pageTitle: '', isTabBarPage: true, customNavigation: false, cusCurrentPage: 0, showLeftContainer: false, currentPath: '', showCustomNavigation: false, showNavCartIcon: false, } function SpPage (props, ref) { const $instance = getCurrentInstance() const [state, setState] = useImmer(initialState) const { cartCount = 0 } = useSelector((state) => state.cart) const { lock, lockStyle, pageTitle, isTabBarPage, customNavigation, cusCurrentPage, showLeftContainer, currentPath, showCustomNavigation, showNavCartIcon } = state const { className, children, renderFloat, renderFooter, scrollToTopBtn = false, isDefault = false, defaultImg = 'empty_data.png', renderDefault, loading = false, defaultMsg = '', navbar = true, onClickLeftIcon = null, navigateTheme = 'light', navigateMantle = false, // 自定义导航,开启滚动蒙层 pageConfig = null, fixedTopContainer = null, isTop = false, isBlack = false, title = '', // 页面导航标题 showNavLogo = false, showNavkfIcon = false, showNavHomeIcon = false, showNavSearchIcon = false, showLogoLoading = false, alwaysBackUrl = '', showNavBackIcon = true } = props let { renderTitle } = props const wrapRef = useRef(null) const scrollTopRef = useRef(0) const sys = useSelector((state) => state.sys) const [showToTop, setShowToTop] = useState(false) const [mantle, setMantle] = useState(false) const { colorPrimary, colorMarketing, colorAccent, rgb, appName } = sys const pageTheme = { '--color-primary': colorPrimary, '--color-marketing': colorMarketing, '--color-accent': colorAccent, '--color-rgb': rgb, '--color-dianwu-primary': '#4980FF' } useReady(() => { // 导购货架数据上报 // const router = $instance.router // console.log('sp pages use ready:', $instance) }) useEffect(() => { if (lock) { setState((draft) => { draft.lockStyle = { position: 'fixed', top: `-${scrollTopRef.current}px`, left: '0px', width: '100%', bottom: '0px' } }) } else { setState((draft) => { draft.lockStyle = {} }) } }, [lock]) useEffect(() => { if (isWeixin || isAlipay) { const pages = Taro.getCurrentPages() const { navigationStyle } = page.config // customNavigation = navigationStyle === 'custom' // cusCurrentPage = pages.length setState(draft => { // draft.customNavigation = navigationStyle === 'custom' draft.customNavigation = true draft.cusCurrentPage = pages.length }) } }, []) useEffect(() => { if (pageConfig) { const { navigateBackgroundColor } = pageConfig if (isAlipay) { my.setNavigationBar({ backgroundColor: navigateBackgroundColor }) } } }, [pageConfig]) useDidShow(() => { const { page, router } = getCurrentInstance() const pageTitle = page?.config?.navigationBarTitleText const fidx = Object.values(TABBAR_PATH).findIndex( (v) => v == $instance.router?.path.split('?')[0] ) const isTabBarPage = fidx > -1 setState((draft) => { draft.currentPath = `${page?.route}` draft.pageTitle = pageTitle draft.isTabBarPage = isTabBarPage draft.showLeftContainer = !['/subpages/guide/index', '/pages/index'].includes(`/${page?.route}`) // '/subpages/member/index', draft.showCustomNavigation = ['/pages/cart/espier-index', '/pages/index', '/pages/category/index', '/pages/recommend/list'].includes(`/${page?.route}`) // draft.showCustomNavigation = true draft.showNavCartIcon = ['/subpages/marketing/coupon-center', '/subpages/marketing/coupon', '/pages/item/list'].includes(`/${page?.route}`) }) // 导购货架分包路由,隐藏所有分享入口 if (router.path.indexOf('/subpages/guide') > -1) { Taro.hideShareMenu({ menus: ["shareAppMessage", "shareTimeline"] }) } }) usePageScroll((res) => { if (!lock) { scrollTopRef.current = res.scrollTop } if (navigateMantle && res.scrollTop > 0) { setMantle(true) } else { setMantle(false) } if (res.scrollTop > 300) { setShowToTop(true) } else { setShowToTop(false) } }) const scrollToTop = () => { Taro.pageScrollTo({ scrollTop: 0, success: () => { Taro.setStorageSync('scrollTop', 0) } }) } useImperativeHandle(ref, () => ({ pageLock: () => { setState((draft) => { draft.lock = true }) }, pageUnLock: () => { setState((draft) => { draft.lock = false }) setTimeout(() => { Taro.pageScrollTo({ scrollTop: scrollTopRef.current, duration: 0 }) }, 0) // console.log('scrollTopRef.current:', scrollTopRef.current) } })) let model = '' let ipx = false let gNavbarH = 0, gStatusBarHeight = 0, gAreaH = 0 // let customNavigation = false // let cusCurrentPage = 0 if (isWeixin || isAlipay) { const deviceInfo = Taro.getSystemInfoSync() // console.log('deviceInfo:', deviceInfo) model = deviceInfo.model ipx = model.search(/iPhone\s*X|iPhone\s*11|iPhone\s*12|iPhone\s*13|iPhone\s*14|iPhone\s*15|iPhone\s*16|iPhone\s*10/g) > -1 const menuButton = Taro.getMenuButtonBoundingClientRect() const { statusBarHeight, safeArea, screenHeight } = deviceInfo gAreaH = (screenHeight - safeArea.bottom) gNavbarH = Math.floor(statusBarHeight + menuButton.height + (menuButton.top - statusBarHeight) * 2) gStatusBarHeight = statusBarHeight } const { page, route } = getCurrentInstance() const _pageTitle = page?.config?.navigationBarTitleText // if (isWeixin) { // const pages = Taro.getCurrentPages() // // const currentPage = pages[pages.length - 1] // const { navigationStyle } = page.config // customNavigation = navigationStyle === 'custom' // cusCurrentPage = pages.length // } const CustomNavigation = () => { // const { page, route } = getCurrentInstance() let pageStyle = {}, pageTitleStyle = {} if (pageConfig) { const { navigateBackgroundColor, navigateStyle, navigateBackgroundImage, titleStyle, titleColor, titleBackgroundImage, titlePosition } = pageConfig // 导航颜色背景 if (navigateStyle == '1') { pageStyle = { 'background-color': "#FFF" || navigateBackgroundColor } } else { pageStyle = { 'background-image': `url(${navigateBackgroundImage})`, 'background-size': '100% 100%', 'background-repeat': 'no-repeat', 'background-position': 'center' } } // 页面标题 if (titleStyle == '1') { renderTitle = {appName} } else if (titleStyle == '2') { renderTitle = } pageTitleStyle = { 'justify-content': titlePosition == 'left' ? 'flex-start' : 'center', 'color': titleColor } } renderTitle = showCustomNavigation || showNavLogo ? : undefined const navigationBarTitleText = props.navigationBarTitleText || getCurrentInstance().page?.config?.navigationBarTitleText return ( { {false && { if (cusCurrentPage == 1) { Taro.redirectTo({ url: isGoodsShelves() ? '/subpages/guide/index' : '/pages/index' }) } else { Taro.navigateBack() } }} /> } {/* */} {showCustomNavigation ? Taro.navigateTo({ url: '/pages/item/list?showSearch=true' })} src={`member/chazhao-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew /> : {showNavBackIcon && { if (alwaysBackUrl) { Taro.navigateTo({ url: alwaysBackUrl, }) return } if (cusCurrentPage == 1) { Taro.redirectTo({ url: isGoodsShelves() ? '/subpages/guide/index' : '/pages/index' }) } else { Taro.navigateBack() } }} />} {showNavCartIcon ? cartCount > 0 ? Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={36} mode='heightFix' isNew /> : Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={36} mode='heightFix' isNew /> : null} {showNavHomeIcon && Taro.redirectTo({ url: '/pages/index' })} height={36} mode='heightFix' isNew />} {showNavSearchIcon && Taro.navigateTo({ url: '/pages/item/list?showSearch=true' })} src={`member/chazhao-${isBlack ? "black" : "light"}.png`} height={34} mode='heightFix' isNew />} } {showNavkfIcon && Taro.redirectTo({ url: '/pages/cart/espier-index' })} height={46} mode='heightFix' isNew />} } {isWeixin && {renderTitle || title || navigationBarTitleText} {/* 吸顶区域 */} {fixedTopContainer} } {showLeftContainer && } ) } let pageBackground = {} if (pageConfig) { const { pageBackgroundStyle, pageBackgroundColor, pageBackgroundImage } = pageConfig if (pageBackgroundStyle == '1') { pageBackground = { 'background-color': "#FFF" || pageBackgroundColor } } else { pageBackground = { 'background-image': `url(${pageBackgroundImage})`, 'background-size': '100% 100%', 'background-position': 'center' } } } return ( {hasNavbar && !isTabBarPage && navbar && ( )} {isDefault && (renderDefault || )} {/* 没有页面自动义头部配置样式,自动生成自定义导航 */} {customNavigation && CustomNavigation()} {/* {loading && } */} {loading && } {showLogoLoading && } {!isDefault && !loading && {children}} {/* 置底操作区 */} {!isDefault && renderFooter && {renderFooter}} {/* 浮动 */} {!isDefault && ( {renderFloat} {showToTop && scrollToTopBtn && ( )} )} ) } export default React.forwardRef(SpPage)