feat(user): 新增收货地址管理及售后申请页面
- 新增地址类型定义,增强前端地址数据结构 - 新增地址编辑页面,支持地址智能识别和定位选点功能 - 地址编辑支持省市区选择及默认地址设置 - 新增地址列表页面,支持地址展示、删除、编辑和选择功能 - 实现售后申请页面,支持选择售后类型和退款原因 - 售后申请支持商品选择、退款金额计算和凭证上传 - 新增售后详情页面,支持售后状态展示及申请取消 - 优化页面加载和用户交互体验,增加错误提示和权限处理
This commit is contained in:
69
src_bak/components/common/VirtualList/index.tsx
Normal file
69
src_bak/components/common/VirtualList/index.tsx
Normal file
@@ -0,0 +1,69 @@
|
||||
import { View, ScrollView } from '@tarojs/components';
|
||||
import { useState, useEffect, useRef, useCallback } from 'react';
|
||||
|
||||
interface VirtualListProps<T> {
|
||||
data: T[];
|
||||
itemHeight: number;
|
||||
containerHeight: number;
|
||||
renderItem: (item: T, index: number) => JSX.Element;
|
||||
keyExtractor: (item: T, index: number) => string | number;
|
||||
onEndReached?: () => void;
|
||||
onEndReachedThreshold?: number;
|
||||
}
|
||||
|
||||
export default function VirtualList<T>({
|
||||
data,
|
||||
itemHeight,
|
||||
containerHeight,
|
||||
renderItem,
|
||||
keyExtractor,
|
||||
onEndReached,
|
||||
onEndReachedThreshold = 0
|
||||
}: VirtualListProps<T>) {
|
||||
const [startIndex, setStartIndex] = useState(0);
|
||||
const [endIndex, setEndIndex] = useState(Math.ceil(containerHeight / itemHeight) + 5);
|
||||
const scrollViewRef = useRef<any>(null);
|
||||
|
||||
const visibleItemCount = Math.ceil(containerHeight / itemHeight) + 10;
|
||||
const offsetY = startIndex * itemHeight;
|
||||
|
||||
const handleScroll = useCallback((e: any) => {
|
||||
const scrollTop = e.detail.scrollTop;
|
||||
const newStartIndex = Math.floor(scrollTop / itemHeight);
|
||||
const newEndIndex = newStartIndex + visibleItemCount;
|
||||
|
||||
setStartIndex(Math.max(0, newStartIndex - 5));
|
||||
setEndIndex(Math.min(data.length, newEndIndex + 5));
|
||||
|
||||
// 触底加载
|
||||
if (onEndReached && onEndReachedThreshold > 0) {
|
||||
const { scrollHeight, clientHeight } = e.detail;
|
||||
if (scrollHeight - scrollTop - clientHeight < onEndReachedThreshold) {
|
||||
onEndReached();
|
||||
}
|
||||
}
|
||||
}, [itemHeight, visibleItemCount, data.length, onEndReached, onEndReachedThreshold]);
|
||||
|
||||
const visibleData = data.slice(startIndex, endIndex);
|
||||
|
||||
return (
|
||||
<ScrollView
|
||||
ref={scrollViewRef}
|
||||
className="w-full"
|
||||
style={{ height: containerHeight }}
|
||||
scrollY
|
||||
onScroll={handleScroll}
|
||||
scrollWithAnimation
|
||||
>
|
||||
<View style={{ height: data.length * itemHeight, position: 'relative' }}>
|
||||
<View style={{ transform: `translateY(${offsetY}px)` }}>
|
||||
{visibleData.map((item, index) => (
|
||||
<View key={keyExtractor(item, startIndex + index)} style={{ height: itemHeight }}>
|
||||
{renderItem(item, startIndex + index)}
|
||||
</View>
|
||||
))}
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user