forked from gxwebsoft/mp-10550
feat(order): 添加下拉刷新功能到订单列表
- 引入 PullToRefresh 组件实现下拉刷新功能 - 将原有滚动容器包装到 PullToRefresh 组件内部 - 实现下拉刷新逻辑,重置分页数据并重新加载 - 设置刷新头部高度为 60 - 保留原有的无限滚动和上拉加载功能
This commit is contained in:
@@ -1,8 +1,7 @@
|
|||||||
import {Avatar, Cell, Space, Empty, Tabs, Button, TabPane, Image, Dialog} from '@nutui/nutui-react-taro'
|
import {Avatar, Cell, Space, Empty, Tabs, Button, TabPane, Image, Dialog, PullToRefresh, InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||||
import {useEffect, useState, useCallback, useRef, CSSProperties} from "react";
|
import {useEffect, useState, useCallback, useRef, CSSProperties} from "react";
|
||||||
import {View, Text} from '@tarojs/components'
|
import {View, Text} from '@tarojs/components'
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import {
|
import {
|
||||||
pageShopOrder,
|
pageShopOrder,
|
||||||
@@ -685,193 +684,202 @@ function OrderList(props: OrderListProps) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
</Tabs>
|
</Tabs>
|
||||||
<View style={getInfiniteUlStyle(props.showSearch)} id="scroll">
|
<PullToRefresh
|
||||||
{error ? (
|
onRefresh={async () => {
|
||||||
<View className="flex flex-col items-center justify-center h-64">
|
setHasMore(true)
|
||||||
<View className="text-gray-500 mb-4">{error}</View>
|
await reload(true)
|
||||||
<Button
|
props.onReload?.()
|
||||||
size="small"
|
}}
|
||||||
type="primary"
|
headHeight={60}
|
||||||
onClick={() => reload(true)}
|
>
|
||||||
|
<View style={getInfiniteUlStyle(props.showSearch)} id="scroll">
|
||||||
|
{error ? (
|
||||||
|
<View className="flex flex-col items-center justify-center h-64">
|
||||||
|
<View className="text-gray-500 mb-4">{error}</View>
|
||||||
|
<Button
|
||||||
|
size="small"
|
||||||
|
type="primary"
|
||||||
|
onClick={() => reload(true)}
|
||||||
|
>
|
||||||
|
重新加载
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<InfiniteLoading
|
||||||
|
target="scroll"
|
||||||
|
hasMore={hasMore}
|
||||||
|
onLoadMore={reloadMore}
|
||||||
|
onScroll={() => {
|
||||||
|
|
||||||
|
}}
|
||||||
|
onScrollToUpper={() => {
|
||||||
|
|
||||||
|
}}
|
||||||
|
loadingText={
|
||||||
|
<>
|
||||||
|
加载中
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
loadMoreText={
|
||||||
|
list.length === 0 ? (
|
||||||
|
<Empty style={{backgroundColor: 'transparent'}} description="您还没有订单哦"/>
|
||||||
|
) : (
|
||||||
|
<View className={'h-24'}>
|
||||||
|
没有更多了
|
||||||
|
</View>
|
||||||
|
)
|
||||||
|
}
|
||||||
>
|
>
|
||||||
重新加载
|
|
||||||
</Button>
|
|
||||||
</View>
|
|
||||||
) : (
|
|
||||||
<InfiniteLoading
|
|
||||||
target="scroll"
|
|
||||||
hasMore={hasMore}
|
|
||||||
onLoadMore={reloadMore}
|
|
||||||
onScroll={() => {
|
|
||||||
|
|
||||||
}}
|
{/* 订单列表 */}
|
||||||
onScrollToUpper={() => {
|
{list.length > 0 && list
|
||||||
|
?.filter((item) => {
|
||||||
}}
|
// “待收货”不展示退款中的/已退款订单,这些订单统一放到“退货/售后”
|
||||||
loadingText={
|
if (tapIndex === 3 && (item.orderStatus === 4 || item.orderStatus === 6)) {
|
||||||
<>
|
return false;
|
||||||
加载中
|
}
|
||||||
</>
|
// “退货/售后”只展示售后相关状态
|
||||||
}
|
if (tapIndex === 5) {
|
||||||
loadMoreText={
|
return item.orderStatus === 4 || item.orderStatus === 5 || item.orderStatus === 6 || item.orderStatus === 7;
|
||||||
list.length === 0 ? (
|
}
|
||||||
<Empty style={{backgroundColor: 'transparent'}} description="您还没有订单哦"/>
|
return true;
|
||||||
) : (
|
})
|
||||||
<View className={'h-24'}>
|
?.map((item, index) => {
|
||||||
没有更多了
|
return (
|
||||||
</View>
|
<Cell key={item.orderId ?? item.orderNo ?? index} style={{padding: '16px'}}
|
||||||
)
|
onClick={() => Taro.navigateTo({url: `/shop/orderDetail/index?orderId=${item.orderId}`})}>
|
||||||
}
|
<Space direction={'vertical'} className={'w-full flex flex-col'}>
|
||||||
>
|
<View className={'order-no flex justify-between'}>
|
||||||
|
<View className={'flex items-center'}>
|
||||||
{/* 订单列表 */}
|
<Text className={'text-gray-600 font-bold text-sm'}
|
||||||
{list.length > 0 && list
|
onClick={(e) => {
|
||||||
?.filter((item) => {
|
e.stopPropagation();
|
||||||
// “待收货”不展示退款中的/已退款订单,这些订单统一放到“退货/售后”
|
copyText(`${item.orderNo}`)
|
||||||
if (tapIndex === 3 && (item.orderStatus === 4 || item.orderStatus === 6)) {
|
}}>{item.orderNo}</Text>
|
||||||
return false;
|
</View>
|
||||||
}
|
{/* 右侧显示合并的状态和倒计时 */}
|
||||||
// “退货/售后”只展示售后相关状态
|
<View className={`${getOrderStatusColor(item)} font-medium`}>
|
||||||
if (tapIndex === 5) {
|
{!item.payStatus && item.orderStatus !== 2 ? (
|
||||||
return item.orderStatus === 4 || item.orderStatus === 5 || item.orderStatus === 6 || item.orderStatus === 7;
|
<PaymentCountdown
|
||||||
}
|
expirationTime={item.expirationTime}
|
||||||
return true;
|
createTime={item.createTime}
|
||||||
})
|
payStatus={item.payStatus}
|
||||||
?.map((item, index) => {
|
realTime={false}
|
||||||
return (
|
showSeconds={false}
|
||||||
<Cell key={item.orderId ?? item.orderNo ?? index} style={{padding: '16px'}}
|
timeoutHours={24}
|
||||||
onClick={() => Taro.navigateTo({url: `/shop/orderDetail/index?orderId=${item.orderId}`})}>
|
mode={'badge'}
|
||||||
<Space direction={'vertical'} className={'w-full flex flex-col'}>
|
/>
|
||||||
<View className={'order-no flex justify-between'}>
|
) : (
|
||||||
<View className={'flex items-center'}>
|
getOrderStatusText(item)
|
||||||
<Text className={'text-gray-600 font-bold text-sm'}
|
)}
|
||||||
onClick={(e) => {
|
</View>
|
||||||
e.stopPropagation();
|
|
||||||
copyText(`${item.orderNo}`)
|
|
||||||
}}>{item.orderNo}</Text>
|
|
||||||
</View>
|
</View>
|
||||||
{/* 右侧显示合并的状态和倒计时 */}
|
<View
|
||||||
<View className={`${getOrderStatusColor(item)} font-medium`}>
|
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</View>
|
||||||
{!item.payStatus && item.orderStatus !== 2 ? (
|
|
||||||
<PaymentCountdown
|
{/* 商品信息 */}
|
||||||
expirationTime={item.expirationTime}
|
<View className={'goods-info'}>
|
||||||
createTime={item.createTime}
|
{item.orderGoods && item.orderGoods.length > 0 ? (
|
||||||
payStatus={item.payStatus}
|
item.orderGoods.map((goods, goodsIndex) => (
|
||||||
realTime={false}
|
<View key={goodsIndex} className={'flex items-center mb-2'}>
|
||||||
showSeconds={false}
|
<Image
|
||||||
timeoutHours={24}
|
src={goods.image || '/default-goods.png'}
|
||||||
mode={'badge'}
|
width="50"
|
||||||
/>
|
height="50"
|
||||||
|
lazyLoad={false}
|
||||||
|
className={'rounded'}
|
||||||
|
/>
|
||||||
|
<View className={'ml-2 flex flex-col flex-1'}>
|
||||||
|
<Text className={'text-sm font-bold'}>
|
||||||
|
{goods.goodsName || (goods as any).goodsTitle || (goods as any).title || item.title || '订单商品'}
|
||||||
|
</Text>
|
||||||
|
{(goods.spec || (goods as any).specInfo) && (
|
||||||
|
<Text className={'text-gray-500 text-xs'}>规格:{goods.spec || (goods as any).specInfo}</Text>
|
||||||
|
)}
|
||||||
|
<Text className={'text-gray-500 text-xs'}>数量:{(goods as any).quantity ?? goods.totalNum}</Text>
|
||||||
|
</View>
|
||||||
|
<Text className={'text-gray-400 text-xs'}>x</Text>
|
||||||
|
<Text className={'text-sm'}>¥{goods.price || (goods as any).payPrice}</Text>
|
||||||
|
</View>
|
||||||
|
))
|
||||||
) : (
|
) : (
|
||||||
getOrderStatusText(item)
|
<View className={'flex items-center'}>
|
||||||
|
<Avatar
|
||||||
|
src='/default-goods.png'
|
||||||
|
size={'50'}
|
||||||
|
shape={'square'}
|
||||||
|
/>
|
||||||
|
<View className={'ml-2'}>
|
||||||
|
<Text className={'text-sm'}>{item.title || '订单商品'}</Text>
|
||||||
|
<Text className={'text-gray-400 text-xs'}>{item.totalNum}件商品</Text>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
)}
|
)}
|
||||||
</View>
|
</View>
|
||||||
</View>
|
|
||||||
<View
|
|
||||||
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</View>
|
|
||||||
|
|
||||||
{/* 商品信息 */}
|
<Text className={'w-full text-right'}>实付金额:¥{item.payPrice}</Text>
|
||||||
<View className={'goods-info'}>
|
|
||||||
{item.orderGoods && item.orderGoods.length > 0 ? (
|
|
||||||
item.orderGoods.map((goods, goodsIndex) => (
|
|
||||||
<View key={goodsIndex} className={'flex items-center mb-2'}>
|
|
||||||
<Image
|
|
||||||
src={goods.image || '/default-goods.png'}
|
|
||||||
width="50"
|
|
||||||
height="50"
|
|
||||||
lazyLoad={false}
|
|
||||||
className={'rounded'}
|
|
||||||
/>
|
|
||||||
<View className={'ml-2 flex flex-col flex-1'}>
|
|
||||||
<Text className={'text-sm font-bold'}>
|
|
||||||
{goods.goodsName || (goods as any).goodsTitle || (goods as any).title || item.title || '订单商品'}
|
|
||||||
</Text>
|
|
||||||
{(goods.spec || (goods as any).specInfo) && (
|
|
||||||
<Text className={'text-gray-500 text-xs'}>规格:{goods.spec || (goods as any).specInfo}</Text>
|
|
||||||
)}
|
|
||||||
<Text className={'text-gray-500 text-xs'}>数量:{(goods as any).quantity ?? goods.totalNum}</Text>
|
|
||||||
</View>
|
|
||||||
<Text className={'text-gray-400 text-xs'}>x</Text>
|
|
||||||
<Text className={'text-sm'}>¥{goods.price || (goods as any).payPrice}</Text>
|
|
||||||
</View>
|
|
||||||
))
|
|
||||||
) : (
|
|
||||||
<View className={'flex items-center'}>
|
|
||||||
<Avatar
|
|
||||||
src='/default-goods.png'
|
|
||||||
size={'50'}
|
|
||||||
shape={'square'}
|
|
||||||
/>
|
|
||||||
<View className={'ml-2'}>
|
|
||||||
<Text className={'text-sm'}>{item.title || '订单商品'}</Text>
|
|
||||||
<Text className={'text-gray-400 text-xs'}>{item.totalNum}件商品</Text>
|
|
||||||
</View>
|
|
||||||
</View>
|
|
||||||
)}
|
|
||||||
</View>
|
|
||||||
|
|
||||||
<Text className={'w-full text-right'}>实付金额:¥{item.payPrice}</Text>
|
{/* 操作按钮 */}
|
||||||
|
{!isReadOnly && (
|
||||||
|
<Space className={'btn flex justify-end'}>
|
||||||
|
{/* 待付款状态:显示取消订单和立即支付 */}
|
||||||
|
{(!item.payStatus) && item.orderStatus !== 2 && (
|
||||||
|
<Space>
|
||||||
|
<Button size={'small'} onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
void cancelOrder(item);
|
||||||
|
}}>取消订单</Button>
|
||||||
|
{(!item.createTime || !isPaymentExpired(item.createTime, 24)) && (
|
||||||
|
<Button size={'small'} type="primary" onClick={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
void payOrder(item);
|
||||||
|
}}>立即支付</Button>
|
||||||
|
)}
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 操作按钮 */}
|
{/* 待发货状态:显示申请退款 */}
|
||||||
{!isReadOnly && (
|
{item.payStatus && isWithinRefundWindow(item.payTime, 60) && item.deliveryStatus === 10 && item.orderStatus !== 2 && item.orderStatus !== 4 && !isOrderCompleted(item) && (
|
||||||
<Space className={'btn flex justify-end'}>
|
|
||||||
{/* 待付款状态:显示取消订单和立即支付 */}
|
|
||||||
{(!item.payStatus) && item.orderStatus !== 2 && (
|
|
||||||
<Space>
|
|
||||||
<Button size={'small'} onClick={(e) => {
|
<Button size={'small'} onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
void cancelOrder(item);
|
applyRefund(item);
|
||||||
}}>取消订单</Button>
|
}}>申请退款</Button>
|
||||||
{(!item.createTime || !isPaymentExpired(item.createTime, 24)) && (
|
)}
|
||||||
|
|
||||||
|
{/* 待收货状态:显示查看物流和确认收货 */}
|
||||||
|
{item.deliveryStatus === 20 && (!item.riderId || !!item.sendEndTime) && item.orderStatus !== 2 && item.orderStatus !== 6 && !isOrderCompleted(item) && (
|
||||||
|
<Space>
|
||||||
|
{/*<Button size={'small'} onClick={(e) => {*/}
|
||||||
|
{/* e.stopPropagation();*/}
|
||||||
|
{/* viewLogistics(item);*/}
|
||||||
|
{/*}}>查看物流</Button>*/}
|
||||||
<Button size={'small'} type="primary" onClick={(e) => {
|
<Button size={'small'} type="primary" onClick={(e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
void payOrder(item);
|
confirmReceive(item);
|
||||||
}}>立即支付</Button>
|
}}>确认收货</Button>
|
||||||
)}
|
</Space>
|
||||||
</Space>
|
)}
|
||||||
)}
|
|
||||||
|
|
||||||
{/* 待发货状态:显示申请退款 */}
|
{/* 退款/售后状态:显示查看进度和撤销申请 */}
|
||||||
{item.payStatus && isWithinRefundWindow(item.payTime, 60) && item.deliveryStatus === 10 && item.orderStatus !== 2 && item.orderStatus !== 4 && !isOrderCompleted(item) && (
|
{(item.orderStatus === 4 || item.orderStatus === 7) && (
|
||||||
<Button size={'small'} onClick={(e) => {
|
<Space>
|
||||||
e.stopPropagation();
|
{/*<Button size={'small'} onClick={(e) => {*/}
|
||||||
applyRefund(item);
|
{/* e.stopPropagation();*/}
|
||||||
}}>申请退款</Button>
|
{/* viewProgress(item);*/}
|
||||||
)}
|
{/*}}>查看进度</Button>*/}
|
||||||
|
</Space>
|
||||||
|
)}
|
||||||
|
|
||||||
{/* 待收货状态:显示查看物流和确认收货 */}
|
</Space>
|
||||||
{item.deliveryStatus === 20 && (!item.riderId || !!item.sendEndTime) && item.orderStatus !== 2 && item.orderStatus !== 6 && !isOrderCompleted(item) && (
|
|
||||||
<Space>
|
|
||||||
{/*<Button size={'small'} onClick={(e) => {*/}
|
|
||||||
{/* e.stopPropagation();*/}
|
|
||||||
{/* viewLogistics(item);*/}
|
|
||||||
{/*}}>查看物流</Button>*/}
|
|
||||||
<Button size={'small'} type="primary" onClick={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
confirmReceive(item);
|
|
||||||
}}>确认收货</Button>
|
|
||||||
</Space>
|
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* 退款/售后状态:显示查看进度和撤销申请 */}
|
|
||||||
{(item.orderStatus === 4 || item.orderStatus === 7) && (
|
|
||||||
<Space>
|
|
||||||
{/*<Button size={'small'} onClick={(e) => {*/}
|
|
||||||
{/* e.stopPropagation();*/}
|
|
||||||
{/* viewProgress(item);*/}
|
|
||||||
{/*}}>查看进度</Button>*/}
|
|
||||||
</Space>
|
|
||||||
)}
|
|
||||||
|
|
||||||
</Space>
|
</Space>
|
||||||
)}
|
</Cell>
|
||||||
</Space>
|
)
|
||||||
</Cell>
|
})}
|
||||||
)
|
</InfiniteLoading>
|
||||||
})}
|
)}
|
||||||
</InfiniteLoading>
|
</View>
|
||||||
)}
|
</PullToRefresh>
|
||||||
</View>
|
|
||||||
|
|
||||||
{/* 取消订单确认对话框 */}
|
{/* 取消订单确认对话框 */}
|
||||||
<Dialog
|
<Dialog
|
||||||
|
|||||||
Reference in New Issue
Block a user