refactor(dealer/orders): 重构订单页面支持分页和下拉刷新

- 添加下拉刷新和上拉加载更多功能
-优化订单数据获取逻辑,支持分页请求
- 移除不必要的订单统计和层级信息
-调整订单列表渲染方式,提高性能
This commit is contained in:
2025-08-28 00:37:29 +08:00
parent a18393f9d6
commit e4e6659752

View File

@@ -1,6 +1,6 @@
import React, {useState, useEffect, useCallback} from 'react' import React, {useState, useEffect, useCallback} from 'react'
import {View, Text} from '@tarojs/components' import {View, Text, ScrollView} from '@tarojs/components'
import {Empty, Tag, Space, PullToRefresh, Loading} from '@nutui/nutui-react-taro' import {Empty, Tag, PullToRefresh, Loading} from '@nutui/nutui-react-taro'
import Taro from '@tarojs/taro' import Taro from '@tarojs/taro'
import {pageShopDealerOrder} from '@/api/shop/shopDealerOrder' import {pageShopDealerOrder} from '@/api/shop/shopDealerOrder'
import {useDealerUser} from '@/hooks/useDealerUser' import {useDealerUser} from '@/hooks/useDealerUser'
@@ -9,85 +9,55 @@ import type {ShopDealerOrder} from '@/api/shop/shopDealerOrder/model'
interface OrderWithDetails extends ShopDealerOrder { interface OrderWithDetails extends ShopDealerOrder {
orderNo?: string orderNo?: string
customerName?: string customerName?: string
totalCommission?: string
// 当前用户在此订单中的层级和佣金
userLevel?: 1 | 2 | 3
userCommission?: string userCommission?: string
} }
const DealerOrders: React.FC = () => { const DealerOrders: React.FC = () => {
const [loading, setLoading] = useState<boolean>(false) const [loading, setLoading] = useState<boolean>(false)
const [refreshing, setRefreshing] = useState<boolean>(false)
const [loadingMore, setLoadingMore] = useState<boolean>(false)
const [orders, setOrders] = useState<OrderWithDetails[]>([]) const [orders, setOrders] = useState<OrderWithDetails[]>([])
const [currentPage, setCurrentPage] = useState<number>(1)
const [hasMore, setHasMore] = useState<boolean>(true)
const {dealerUser} = useDealerUser() const {dealerUser} = useDealerUser()
// 获取订单数据 - 查询当前用户作为各层级分销商的所有订单 // 获取订单数据
const fetchOrders = useCallback(async () => { const fetchOrders = useCallback(async (page: number = 1, isRefresh: boolean = false) => {
if (!dealerUser?.userId) return if (!dealerUser?.userId) return
try { try {
setLoading(true) if (isRefresh) {
setRefreshing(true)
// 并行查询三个层级的订单 } else if (page === 1) {
const [level1Result] = await Promise.all([ setLoading(true)
// 一级分销商订单 } else {
pageShopDealerOrder({ setLoadingMore(true)
page: 1,
limit: 10
})
])
const allOrders: OrderWithDetails[] = []
const stats = {
totalOrders: 0,
totalCommission: '0.00',
pendingCommission: '0.00',
level1: {orders: 0, commission: '0.00'},
level2: {orders: 0, commission: '0.00'},
level3: {orders: 0, commission: '0.00'}
} }
// 处理一级分销订单 const result = await pageShopDealerOrder({
if (level1Result?.list) { page,
const level1Orders = level1Result.list.map(order => ({ limit: 10
})
if (result?.list) {
const newOrders = result.list.map(order => ({
...order, ...order,
orderNo: `${order.orderId}`, orderNo: `${order.orderId}`,
customerName: `用户${order.userId}`, customerName: `用户${order.userId}`,
userLevel: 1 as const, userCommission: order.firstMoney || '0.00'
userCommission: order.firstMoney || '0.00',
totalCommission: (
parseFloat(order.firstMoney || '0') +
parseFloat(order.secondMoney || '0') +
parseFloat(order.thirdMoney || '0')
).toFixed(2)
})) }))
allOrders.push(...level1Orders) if (page === 1) {
stats.level1.orders = level1Orders.length setOrders(newOrders)
stats.level1.commission = level1Orders.reduce((sum, order) => } else {
sum + parseFloat(order.userCommission || '0'), 0 setOrders(prev => [...prev, ...newOrders])
).toFixed(2) }
setHasMore(newOrders.length === 10)
setCurrentPage(page)
} }
// 去重(同一个订单可能在多个层级中出现)
const uniqueOrders = allOrders.filter((order, index, self) =>
index === self.findIndex(o => o.orderId === order.orderId)
)
// 计算总统计
stats.totalOrders = uniqueOrders.length
stats.totalCommission = (
parseFloat(stats.level1.commission) +
parseFloat(stats.level2.commission) +
parseFloat(stats.level3.commission)
).toFixed(2)
stats.pendingCommission = allOrders
.filter(order => order.isSettled === 0)
.reduce((sum, order) => sum + parseFloat(order.userCommission || '0'), 0)
.toFixed(2)
setOrders(uniqueOrders)
} catch (error) { } catch (error) {
console.error('获取分销订单失败:', error) console.error('获取分销订单失败:', error)
Taro.showToast({ Taro.showToast({
@@ -96,18 +66,27 @@ const DealerOrders: React.FC = () => {
}) })
} finally { } finally {
setLoading(false) setLoading(false)
setRefreshing(false)
setLoadingMore(false)
} }
}, [dealerUser?.userId]) }, [dealerUser?.userId])
// 刷新数据 // 下拉刷新
const handleRefresh = async () => { const handleRefresh = async () => {
await fetchOrders() await fetchOrders(1, true)
}
// 加载更多
const handleLoadMore = async () => {
if (!loadingMore && hasMore) {
await fetchOrders(currentPage + 1)
}
} }
// 初始化加载数据 // 初始化加载数据
useEffect(() => { useEffect(() => {
if (dealerUser?.userId) { if (dealerUser?.userId) {
fetchOrders().then() fetchOrders(1)
} }
}, [fetchOrders]) }, [fetchOrders])
@@ -126,34 +105,21 @@ const DealerOrders: React.FC = () => {
const renderOrderItem = (order: OrderWithDetails) => ( const renderOrderItem = (order: OrderWithDetails) => (
<View key={order.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm"> <View key={order.id} className="bg-white rounded-lg p-4 mb-3 shadow-sm">
<View className="flex justify-between items-start mb-1"> <View className="flex justify-between items-start mb-1">
<Space> <Text className="font-semibold text-gray-800">
<Text className="font-semibold text-gray-800"> {order.orderNo}
{order.orderNo} </Text>
</Text>
{/* 显示用户在此订单中的层级 */}
{/*<Text className="text-xs text-blue-500">*/}
{/* {order.userLevel === 1 && '一级分销'}*/}
{/* {order.userLevel === 2 && '二级分销'}*/}
{/* {order.userLevel === 3 && '三级分销'}*/}
{/*</Text>*/}
</Space>
<Tag type={getStatusColor(order.isSettled, order.isInvalid)}> <Tag type={getStatusColor(order.isSettled, order.isInvalid)}>
{getStatusText(order.isSettled, order.isInvalid)} {getStatusText(order.isSettled, order.isInvalid)}
</Tag> </Tag>
</View> </View>
<View className="flex justify-between items-center mb-1"> <View className="flex justify-between items-center mb-1">
<Space> <Text className="text-sm text-gray-400">
<Text className="text-sm text-gray-400"> ¥{order.orderPrice || '0.00'}
¥{order.orderPrice || '0.00'} </Text>
</Text> <Text className="text-sm text-orange-500 font-semibold">
<Text className="text-sm text-orange-500 font-semibold"> ¥{order.userCommission}
¥{order.userCommission} </Text>
</Text>
{/*<Text className="text-xs text-gray-400">*/}
{/* 总佣金:¥{order.totalCommission}*/}
{/*</Text>*/}
</Space>
</View> </View>
<View className="flex justify-between items-center"> <View className="flex justify-between items-center">
@@ -167,26 +133,6 @@ const DealerOrders: React.FC = () => {
</View> </View>
) )
// 根据状态和层级过滤订单
const getFilteredOrders = (filter: string) => {
switch (filter) {
case '1': // 一级分销
return orders.filter(order => order.userLevel === 1)
case '2': // 二级分销
return orders.filter(order => order.userLevel === 2)
case '3': // 三级分销
return orders.filter(order => order.userLevel === 3)
case '4': // 待结算
return orders.filter(order => order.isSettled === 0 && order.isInvalid === 0)
case '5': // 已结算
return orders.filter(order => order.isSettled === 1)
case '6': // 已失效
return orders.filter(order => order.isInvalid === 1)
default: // 全部
return orders
}
}
if (!dealerUser) { if (!dealerUser) {
return ( return (
<View className="bg-gray-50 min-h-screen flex items-center justify-center"> <View className="bg-gray-50 min-h-screen flex items-center justify-center">
@@ -197,20 +143,48 @@ const DealerOrders: React.FC = () => {
} }
return ( return (
<View className="min-h-screen"> <View className="min-h-screen bg-gray-50">
{/* 订单列表 */} <PullToRefresh
<View className="p-4"> onRefresh={handleRefresh}
{loading ? ( disabled={refreshing}
<View className="text-center py-8"> pullingText="下拉刷新"
<Loading/> canReleaseText="释放刷新"
<Text className="text-gray-500 mt-2">...</Text> refreshingText="刷新中..."
completeText="刷新完成"
>
<ScrollView
scrollY
className="h-screen"
onScrollToLower={handleLoadMore}
lowerThreshold={50}
>
<View className="p-4">
{loading && orders.length === 0 ? (
<View className="text-center py-8">
<Loading/>
<Text className="text-gray-500 mt-2">...</Text>
</View>
) : orders.length > 0 ? (
<>
{orders.map(renderOrderItem)}
{loadingMore && (
<View className="text-center py-4">
<Loading/>
<Text className="text-gray-500 mt-1 text-sm">...</Text>
</View>
)}
{!hasMore && orders.length > 0 && (
<View className="text-center py-4">
<Text className="text-gray-400 text-sm"></Text>
</View>
)}
</>
) : (
<Empty description="暂无分销订单"/>
)}
</View> </View>
) : getFilteredOrders('0').length > 0 ? ( </ScrollView>
getFilteredOrders('0').map(renderOrderItem) </PullToRefresh>
) : (
<Empty description="暂无分销订单"/>
)}
</View>
</View> </View>
) )
} }