|  | @@ -1,116 +1,145 @@
 | 
	
		
			
				|  |  | -import { ScrollView } from "@tarojs/components"
 | 
	
		
			
				|  |  | -import { Component } from "react"
 | 
	
		
			
				|  |  | -import { UpLoading } from "@src/components/PupPetry/Loading"
 | 
	
		
			
				|  |  | -import Taro from "@tarojs/taro"
 | 
	
		
			
				|  |  | +import { ScrollView } from "@tarojs/components";
 | 
	
		
			
				|  |  | +import { Component } from "react";
 | 
	
		
			
				|  |  | +import { UpLoading } from "@src/components/PupPetry/Loading";
 | 
	
		
			
				|  |  | +import Taro from "@tarojs/taro";
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  interface State {
 | 
	
		
			
				|  |  | -    isShow: boolean  //是否开启刷新状态
 | 
	
		
			
				|  |  | -    isBoShow: boolean, //是否开启下拉刷新状态
 | 
	
		
			
				|  |  | -    isNull: boolean,  // 是否还有数据
 | 
	
		
			
				|  |  | -    filterHeight: number,//容器排除的高度
 | 
	
		
			
				|  |  | +  isShow: boolean; // 是否开启刷新状态
 | 
	
		
			
				|  |  | +  isBoShow: boolean; // 是否开启下拉刷新状态
 | 
	
		
			
				|  |  | +  isNull: boolean; // 是否还有数据
 | 
	
		
			
				|  |  | +  filterHeight: number; // 容器排除的高度
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  interface Props {
 | 
	
		
			
				|  |  | -    children: any,//渲染的子元素
 | 
	
		
			
				|  |  | -    filterClassName: string,//要排除的元素的高度
 | 
	
		
			
				|  |  | -    navHeight: number,//头部导航高度
 | 
	
		
			
				|  |  | -    refresh?: () => Promise<any>,//刷新
 | 
	
		
			
				|  |  | -    load?: () => Promise<any>,//加载
 | 
	
		
			
				|  |  | -    callback?: (num: any) => void,//返回滚动距离
 | 
	
		
			
				|  |  | +  children: any; // 渲染的子元素
 | 
	
		
			
				|  |  | +  filterClassName: string; // 要排除的元素的高度
 | 
	
		
			
				|  |  | +  navHeight: number; // 头部导航高度
 | 
	
		
			
				|  |  | +  refresh?: () => Promise<any>; // 刷新
 | 
	
		
			
				|  |  | +  load?: () => Promise<any>; // 加载
 | 
	
		
			
				|  |  | +  callback?: (num: any) => void; // 返回滚动距离
 | 
	
		
			
				|  |  | +  reloadState?: boolean;
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  /**页面上下加载*/
 | 
	
		
			
				|  |  | -class ScrollViewHoc extends Component<Props> {
 | 
	
		
			
				|  |  | -    constructor(props) {
 | 
	
		
			
				|  |  | -        super(props)
 | 
	
		
			
				|  |  | -    }
 | 
	
		
			
				|  |  | -    state: State = {
 | 
	
		
			
				|  |  | -        isShow: false,
 | 
	
		
			
				|  |  | -        isBoShow: false,
 | 
	
		
			
				|  |  | -        isNull: false,
 | 
	
		
			
				|  |  | -        filterHeight: 0,
 | 
	
		
			
				|  |  | +class ScrollViewHoc extends Component<Props, State> {
 | 
	
		
			
				|  |  | +  constructor(props: Props) {
 | 
	
		
			
				|  |  | +    super(props);
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  state: State = {
 | 
	
		
			
				|  |  | +    isShow: false,
 | 
	
		
			
				|  |  | +    isBoShow: false,
 | 
	
		
			
				|  |  | +    isNull: false,
 | 
	
		
			
				|  |  | +    filterHeight: 0,
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  //**向上刷新 */
 | 
	
		
			
				|  |  | +  onScrollToUpper = () => {
 | 
	
		
			
				|  |  | +    if (!this.props.refresh) {
 | 
	
		
			
				|  |  | +      setTimeout(() => {
 | 
	
		
			
				|  |  | +        this.setState({ isShow: false });
 | 
	
		
			
				|  |  | +      }, 500);
 | 
	
		
			
				|  |  | +      console.log("请传入自定义refresh事件");
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    //**向上刷新 */
 | 
	
		
			
				|  |  | -    onScrollToUpper = () => {
 | 
	
		
			
				|  |  | -        if (!this.props.refresh) {
 | 
	
		
			
				|  |  | -            setTimeout(() => { this.setState({ isShow: false }) }, 500)
 | 
	
		
			
				|  |  | -            log('请传入自定义refresh事件')
 | 
	
		
			
				|  |  | -            return
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        let { isShow } = this.state
 | 
	
		
			
				|  |  | -        log(isShow)
 | 
	
		
			
				|  |  | -        if (!isShow) {
 | 
	
		
			
				|  |  | -            log('下拉')
 | 
	
		
			
				|  |  | -            this.setState({ isShow: true }, async () => {
 | 
	
		
			
				|  |  | -                if (this?.props?.refresh) {
 | 
	
		
			
				|  |  | -                    await this?.props?.refresh().then(() => {
 | 
	
		
			
				|  |  | -                        setTimeout(() => { this.setState({ isShow: false }) }, 500)
 | 
	
		
			
				|  |  | -                    })
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            })
 | 
	
		
			
				|  |  | +    let { isShow } = this.state;
 | 
	
		
			
				|  |  | +    console.log(isShow);
 | 
	
		
			
				|  |  | +    if (!isShow) {
 | 
	
		
			
				|  |  | +      console.log("下拉");
 | 
	
		
			
				|  |  | +      this.setState({ isShow: true }, async () => {
 | 
	
		
			
				|  |  | +        if (this?.props?.refresh) {
 | 
	
		
			
				|  |  | +          await this?.props?.refresh().then(() => {
 | 
	
		
			
				|  |  | +            setTimeout(() => {
 | 
	
		
			
				|  |  | +              this.setState({ isShow: false });
 | 
	
		
			
				|  |  | +            }, 500);
 | 
	
		
			
				|  |  | +          });
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    /**向下加载 */
 | 
	
		
			
				|  |  | -    onScrollToLower = () => {
 | 
	
		
			
				|  |  | -        if (!this.props.load) {
 | 
	
		
			
				|  |  | -            log('请传入自定义load事件')
 | 
	
		
			
				|  |  | -            return
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | -        let { isBoShow } = this.state
 | 
	
		
			
				|  |  | -        if (!isBoShow) {
 | 
	
		
			
				|  |  | -            log('上拉')
 | 
	
		
			
				|  |  | -            this.setState({ isBoShow: true }, () => {
 | 
	
		
			
				|  |  | -                if (this?.props?.load) {
 | 
	
		
			
				|  |  | -                    this?.props?.load().then(res => {
 | 
	
		
			
				|  |  | -                        this.setState({ isNull: false })
 | 
	
		
			
				|  |  | -                    }).catch(e => {
 | 
	
		
			
				|  |  | -                        this.setState({ isNull: true, isBoShow: false })
 | 
	
		
			
				|  |  | -                    })
 | 
	
		
			
				|  |  | -                    setTimeout(() => { this.setState({ isBoShow: false }) }, 500)
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  /**向下加载 */
 | 
	
		
			
				|  |  | +  onScrollToLower = () => {
 | 
	
		
			
				|  |  | +    if (!this.props.load) {
 | 
	
		
			
				|  |  | +      console.log("请传入自定义load事件");
 | 
	
		
			
				|  |  | +      return;
 | 
	
		
			
				|  |  | +    }
 | 
	
		
			
				|  |  | +    let { isBoShow } = this.state;
 | 
	
		
			
				|  |  | +    if (!isBoShow) {
 | 
	
		
			
				|  |  | +      console.log("上拉");
 | 
	
		
			
				|  |  | +      this.setState({ isBoShow: true }, () => {
 | 
	
		
			
				|  |  | +        if (this?.props?.load) {
 | 
	
		
			
				|  |  | +          this?.props?.load()
 | 
	
		
			
				|  |  | +            .then(() => {
 | 
	
		
			
				|  |  | +              this.setState({ isNull: false });
 | 
	
		
			
				|  |  |              })
 | 
	
		
			
				|  |  | +            .catch(() => {
 | 
	
		
			
				|  |  | +              this.setState({ isNull: true, isBoShow: false });
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +          setTimeout(() => {
 | 
	
		
			
				|  |  | +            this.setState({ isBoShow: false });
 | 
	
		
			
				|  |  | +          }, 500);
 | 
	
		
			
				|  |  |          }
 | 
	
		
			
				|  |  | +      });
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    componentDidMount() {
 | 
	
		
			
				|  |  | -        let { filterClassName, navHeight = 0 } = this.props
 | 
	
		
			
				|  |  | -        if (filterClassName) {
 | 
	
		
			
				|  |  | -            Taro.createSelectorQuery()
 | 
	
		
			
				|  |  | -                .select(filterClassName) // 选择器,用于选择要获取信息的元素
 | 
	
		
			
				|  |  | -                .boundingClientRect() // 获取节点的布局信息
 | 
	
		
			
				|  |  | -                .exec((res) => {
 | 
	
		
			
				|  |  | -                    if (res[0]) {
 | 
	
		
			
				|  |  | -                        const height = res[0].height; // 获取元素的高度
 | 
	
		
			
				|  |  | -                        this.setState({ filterHeight: height + navHeight })
 | 
	
		
			
				|  |  | -                    } else {
 | 
	
		
			
				|  |  | -                        console.log('未找到指定元素');
 | 
	
		
			
				|  |  | -                    }
 | 
	
		
			
				|  |  | -                });
 | 
	
		
			
				|  |  | -        }
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 初始获取 filterClassName 元素的高度
 | 
	
		
			
				|  |  | +  componentDidMount() {
 | 
	
		
			
				|  |  | +    this.calculateFilterHeight();
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +  // 当 reloadState 变化时重新获取 filterClassName 元素的高度
 | 
	
		
			
				|  |  | +  componentDidUpdate(prevProps: Props) {
 | 
	
		
			
				|  |  | +    if (prevProps.reloadState !== this.props.reloadState) {
 | 
	
		
			
				|  |  | +      this.calculateFilterHeight();
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -    render() {
 | 
	
		
			
				|  |  | -        const { children } = this.props
 | 
	
		
			
				|  |  | -        const { filterHeight } = this.state
 | 
	
		
			
				|  |  | -        return <ScrollView
 | 
	
		
			
				|  |  | -            lowerThreshold={filterHeight}
 | 
	
		
			
				|  |  | -            refresherTriggered={this.state.isShow}
 | 
	
		
			
				|  |  | -            style={{ height: `calc(100vh - ${filterHeight}px)` }}
 | 
	
		
			
				|  |  | -            onScrollToLower={this.onScrollToLower}
 | 
	
		
			
				|  |  | -            onScroll={(evt) => {
 | 
	
		
			
				|  |  | -                this.props.callback?.(evt.detail.scrollTop)
 | 
	
		
			
				|  |  | -            }}
 | 
	
		
			
				|  |  | -            className='scrollview'
 | 
	
		
			
				|  |  | -            scrollY={true}
 | 
	
		
			
				|  |  | -            onRefresherRefresh={() => { this.onScrollToUpper() }}
 | 
	
		
			
				|  |  | -            refresherDefaultStyle='black'
 | 
	
		
			
				|  |  | -            scrollWithAnimation={true}
 | 
	
		
			
				|  |  | -        >
 | 
	
		
			
				|  |  | -            <>
 | 
	
		
			
				|  |  | -                {children}
 | 
	
		
			
				|  |  | -                {
 | 
	
		
			
				|  |  | -                    this.state.isBoShow && <UpLoading />
 | 
	
		
			
				|  |  | -                }
 | 
	
		
			
				|  |  | -            </>
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -        </ScrollView>
 | 
	
		
			
				|  |  | +  calculateFilterHeight = () => {
 | 
	
		
			
				|  |  | +    let { filterClassName, navHeight = 0 } = this.props;
 | 
	
		
			
				|  |  | +    if (filterClassName) {
 | 
	
		
			
				|  |  | +      Taro.createSelectorQuery()
 | 
	
		
			
				|  |  | +        .select(filterClassName) // 选择器,用于选择要获取信息的元素
 | 
	
		
			
				|  |  | +        .boundingClientRect() // 获取节点的布局信息
 | 
	
		
			
				|  |  | +        .exec((res) => {
 | 
	
		
			
				|  |  | +          if (res[0]) {
 | 
	
		
			
				|  |  | +            const height = res[0].height; // 获取元素的高度
 | 
	
		
			
				|  |  | +            this.setState({ filterHeight: height + navHeight });
 | 
	
		
			
				|  |  | +          } else {
 | 
	
		
			
				|  |  | +            console.log("未找到指定元素");
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  |      }
 | 
	
		
			
				|  |  | -}
 | 
	
		
			
				|  |  | +  };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +  render() {
 | 
	
		
			
				|  |  | +    const { children, reloadState } = this.props;
 | 
	
		
			
				|  |  | +    const { filterHeight } = this.state;
 | 
	
		
			
				|  |  | +    return (
 | 
	
		
			
				|  |  | +      <ScrollView
 | 
	
		
			
				|  |  | +        lowerThreshold={filterHeight}
 | 
	
		
			
				|  |  | +        refresherTriggered={this.state.isShow}
 | 
	
		
			
				|  |  | +        style={{ height: `calc(100vh - ${filterHeight}px)` }}
 | 
	
		
			
				|  |  | +        onScrollToLower={this.onScrollToLower}
 | 
	
		
			
				|  |  | +        onScroll={(evt) => {
 | 
	
		
			
				|  |  | +          this.props.callback?.(evt.detail.scrollTop);
 | 
	
		
			
				|  |  | +        }}
 | 
	
		
			
				|  |  | +        className="scrollview"
 | 
	
		
			
				|  |  | +        scrollY={true}
 | 
	
		
			
				|  |  | +        onRefresherRefresh={() => {
 | 
	
		
			
				|  |  | +          this.onScrollToUpper();
 | 
	
		
			
				|  |  | +        }}
 | 
	
		
			
				|  |  | +        refresherDefaultStyle="black"
 | 
	
		
			
				|  |  | +        scrollWithAnimation={true}
 | 
	
		
			
				|  |  | +      >
 | 
	
		
			
				|  |  | +        <>
 | 
	
		
			
				|  |  | +          {children}
 | 
	
		
			
				|  |  | +          {this.state.isBoShow && <UpLoading />}
 | 
	
		
			
				|  |  | +        </>
 | 
	
		
			
				|  |  | +      </ScrollView>
 | 
	
		
			
				|  |  | +    );
 | 
	
		
			
				|  |  | +  }
 | 
	
		
			
				|  |  | +}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -export default ScrollViewHoc
 | 
	
		
			
				|  |  | +export default ScrollViewHoc;
 |