|
@ -1,4 +1,4 @@ |
|
|
import {Avatar, Cell, Space, Tabs, Button, TabPane, Image} from '@nutui/nutui-react-taro' |
|
|
|
|
|
|
|
|
import {Avatar, Cell, Space, Empty, Tabs, Button, TabPane, Image} from '@nutui/nutui-react-taro' |
|
|
import {useEffect, useState, CSSProperties} from "react"; |
|
|
import {useEffect, useState, CSSProperties} from "react"; |
|
|
import {View} from '@tarojs/components' |
|
|
import {View} from '@tarojs/components' |
|
|
import Taro from '@tarojs/taro'; |
|
|
import Taro from '@tarojs/taro'; |
|
@ -27,7 +27,7 @@ const tabs = [ |
|
|
key: '全部', |
|
|
key: '全部', |
|
|
title: '全部', |
|
|
title: '全部', |
|
|
description: '所有订单', |
|
|
description: '所有订单', |
|
|
statusFilter: undefined // 不传statusFilter,显示所有订单
|
|
|
|
|
|
|
|
|
statusFilter: -1 // 使用-1表示全部订单
|
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
index: 1, |
|
|
index: 1, |
|
@ -59,9 +59,9 @@ const tabs = [ |
|
|
}, |
|
|
}, |
|
|
{ |
|
|
{ |
|
|
index: 5, |
|
|
index: 5, |
|
|
key: '已取消', |
|
|
|
|
|
title: '已取消', |
|
|
|
|
|
description: '已取消/退款的订单', |
|
|
|
|
|
|
|
|
key: '退货/售后', |
|
|
|
|
|
title: '退货/售后', |
|
|
|
|
|
description: '退货/售后的订单', |
|
|
statusFilter: 6 // 对应后端:order_status = 6 (已退款)
|
|
|
statusFilter: 6 // 对应后端:order_status = 6 (已退款)
|
|
|
} |
|
|
} |
|
|
] |
|
|
] |
|
@ -84,10 +84,6 @@ function OrderList(props: OrderListProps) { |
|
|
// 根据传入的statusFilter设置初始tab索引
|
|
|
// 根据传入的statusFilter设置初始tab索引
|
|
|
const getInitialTabIndex = () => { |
|
|
const getInitialTabIndex = () => { |
|
|
if (props.searchParams?.statusFilter !== undefined) { |
|
|
if (props.searchParams?.statusFilter !== undefined) { |
|
|
// 如果statusFilter为-1,表示全部,对应index为0
|
|
|
|
|
|
if (props.searchParams.statusFilter === -1) { |
|
|
|
|
|
return 0; |
|
|
|
|
|
} |
|
|
|
|
|
const tab = tabs.find(t => t.statusFilter === props.searchParams?.statusFilter); |
|
|
const tab = tabs.find(t => t.statusFilter === props.searchParams?.statusFilter); |
|
|
return tab ? tab.index : 0; |
|
|
return tab ? tab.index : 0; |
|
|
} |
|
|
} |
|
@ -117,7 +113,7 @@ function OrderList(props: OrderListProps) { |
|
|
// 已付款后检查发货状态
|
|
|
// 已付款后检查发货状态
|
|
|
if (order.deliveryStatus === 10) return '待发货'; |
|
|
if (order.deliveryStatus === 10) return '待发货'; |
|
|
if (order.deliveryStatus === 20) return '待收货'; |
|
|
if (order.deliveryStatus === 20) return '待收货'; |
|
|
if (order.deliveryStatus === 30) return '已收货'; |
|
|
|
|
|
|
|
|
if (order.deliveryStatus === 30) return '已完成'; |
|
|
|
|
|
|
|
|
// 最后检查订单完成状态
|
|
|
// 最后检查订单完成状态
|
|
|
if (order.orderStatus === 1) return '已完成'; |
|
|
if (order.orderStatus === 1) return '已完成'; |
|
@ -161,6 +157,7 @@ function OrderList(props: OrderListProps) { |
|
|
if (currentTab && currentTab.statusFilter !== undefined) { |
|
|
if (currentTab && currentTab.statusFilter !== undefined) { |
|
|
params.statusFilter = currentTab.statusFilter; |
|
|
params.statusFilter = currentTab.statusFilter; |
|
|
} |
|
|
} |
|
|
|
|
|
// 注意:当statusFilter为undefined时,不要添加到params中,这样API请求就不会包含这个参数
|
|
|
|
|
|
|
|
|
console.log(`Tab ${index} (${currentTab?.title}) 筛选参数:`, params); |
|
|
console.log(`Tab ${index} (${currentTab?.title}) 筛选参数:`, params); |
|
|
return params; |
|
|
return params; |
|
@ -172,16 +169,21 @@ function OrderList(props: OrderListProps) { |
|
|
const currentPage = resetPage ? 1 : (targetPage || page); |
|
|
const currentPage = resetPage ? 1 : (targetPage || page); |
|
|
const statusParams = getOrderStatusParams(tapIndex); |
|
|
const statusParams = getOrderStatusParams(tapIndex); |
|
|
// 合并搜索条件,tab的statusFilter优先级更高
|
|
|
// 合并搜索条件,tab的statusFilter优先级更高
|
|
|
const searchConditions = { |
|
|
|
|
|
|
|
|
const searchConditions: any = { |
|
|
page: currentPage, |
|
|
page: currentPage, |
|
|
userId: statusParams.userId, // 用户ID
|
|
|
userId: statusParams.userId, // 用户ID
|
|
|
...props.searchParams, // 搜索关键词等其他条件
|
|
|
...props.searchParams, // 搜索关键词等其他条件
|
|
|
statusFilter: statusParams.statusFilter // tab的statusFilter优先级最高
|
|
|
|
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
// statusFilter总是添加到搜索条件中(包括-1表示全部)
|
|
|
|
|
|
if (statusParams.statusFilter !== undefined) { |
|
|
|
|
|
searchConditions.statusFilter = statusParams.statusFilter; |
|
|
|
|
|
} |
|
|
console.log('订单筛选条件:', { |
|
|
console.log('订单筛选条件:', { |
|
|
tapIndex, |
|
|
tapIndex, |
|
|
statusParams, |
|
|
statusParams, |
|
|
searchConditions |
|
|
|
|
|
|
|
|
searchConditions, |
|
|
|
|
|
finalStatusFilter: searchConditions.statusFilter |
|
|
}); |
|
|
}); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
@ -198,7 +200,7 @@ function OrderList(props: OrderListProps) { |
|
|
const batchResults = await Promise.all( |
|
|
const batchResults = await Promise.all( |
|
|
batch.map(async (order) => { |
|
|
batch.map(async (order) => { |
|
|
try { |
|
|
try { |
|
|
const orderGoods = await listShopOrderGoods({ orderId: order.orderId }); |
|
|
|
|
|
|
|
|
const orderGoods = await listShopOrderGoods({orderId: order.orderId}); |
|
|
return { |
|
|
return { |
|
|
...order, |
|
|
...order, |
|
|
orderGoods: orderGoods || [] |
|
|
orderGoods: orderGoods || [] |
|
@ -306,10 +308,34 @@ function OrderList(props: OrderListProps) { |
|
|
reload(true).then(); // 首次加载或tab切换时重置页码
|
|
|
reload(true).then(); // 首次加载或tab切换时重置页码
|
|
|
}, [tapIndex]); // 监听tapIndex变化
|
|
|
}, [tapIndex]); // 监听tapIndex变化
|
|
|
|
|
|
|
|
|
|
|
|
// 监听外部statusFilter变化,同步更新tab索引
|
|
|
useEffect(() => { |
|
|
useEffect(() => { |
|
|
// 当外部传入的搜索参数变化时(不包括statusFilter,因为tab切换会处理)
|
|
|
|
|
|
|
|
|
// 获取当前的statusFilter,如果未定义则默认为-1(全部)
|
|
|
|
|
|
const currentStatusFilter = props.searchParams?.statusFilter !== undefined |
|
|
|
|
|
? props.searchParams.statusFilter |
|
|
|
|
|
: -1; |
|
|
|
|
|
|
|
|
|
|
|
const tab = tabs.find(t => t.statusFilter === currentStatusFilter); |
|
|
|
|
|
const targetTabIndex = tab ? tab.index : 0; |
|
|
|
|
|
|
|
|
|
|
|
console.log('外部statusFilter变化:', { |
|
|
|
|
|
statusFilter: currentStatusFilter, |
|
|
|
|
|
originalStatusFilter: props.searchParams?.statusFilter, |
|
|
|
|
|
currentTapIndex: tapIndex, |
|
|
|
|
|
targetTabIndex, |
|
|
|
|
|
shouldUpdate: targetTabIndex !== tapIndex |
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
if (targetTabIndex !== tapIndex) { |
|
|
|
|
|
setTapIndex(targetTabIndex); |
|
|
|
|
|
// 不需要调用reload,因为tapIndex变化会触发reload
|
|
|
|
|
|
} |
|
|
|
|
|
}, [props.searchParams?.statusFilter]); // 监听statusFilter变化
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => { |
|
|
|
|
|
// 当外部传入的搜索参数变化时(不包括statusFilter,因为上面已经处理)
|
|
|
// 只有当搜索关键词等其他条件变化时才重新加载
|
|
|
// 只有当搜索关键词等其他条件变化时才重新加载
|
|
|
const { statusFilter, ...otherParams } = props.searchParams || {}; |
|
|
|
|
|
|
|
|
const {statusFilter, ...otherParams} = props.searchParams || {}; |
|
|
|
|
|
|
|
|
// 检查是否有除statusFilter外的其他搜索条件变化
|
|
|
// 检查是否有除statusFilter外的其他搜索条件变化
|
|
|
const hasOtherSearchParams = Object.keys(otherParams).some(key => |
|
|
const hasOtherSearchParams = Object.keys(otherParams).some(key => |
|
@ -385,82 +411,104 @@ function OrderList(props: OrderListProps) { |
|
|
</> |
|
|
</> |
|
|
} |
|
|
} |
|
|
loadMoreText={ |
|
|
loadMoreText={ |
|
|
<View className={'h-24'}> |
|
|
|
|
|
没有更多了 |
|
|
|
|
|
</View> |
|
|
|
|
|
|
|
|
list.length === 0 ? ( |
|
|
|
|
|
<Empty style={{ backgroundColor: 'transparent' }} description="您还没有订单哦"/> |
|
|
|
|
|
) : ( |
|
|
|
|
|
<View className={'h-24'}> |
|
|
|
|
|
没有更多了 |
|
|
|
|
|
</View> |
|
|
|
|
|
) |
|
|
} |
|
|
} |
|
|
> |
|
|
> |
|
|
{list?.map((item, index) => { |
|
|
|
|
|
return ( |
|
|
|
|
|
<Cell key={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={'text-gray-600 font-bold text-sm'} |
|
|
|
|
|
onClick={(e) => {e.stopPropagation(); copyText(`${item.orderNo}`)}}>{item.orderNo}</View> |
|
|
|
|
|
<View className={`${getOrderStatusColor(item)} font-medium`}>{getOrderStatusText(item)}</View> |
|
|
|
|
|
</View> |
|
|
|
|
|
<div |
|
|
|
|
|
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</div> |
|
|
|
|
|
|
|
|
|
|
|
{/* 商品信息 */} |
|
|
|
|
|
<div className={'goods-info'}> |
|
|
|
|
|
{item.orderGoods && item.orderGoods.length > 0 ? ( |
|
|
|
|
|
item.orderGoods.map((goods, goodsIndex) => ( |
|
|
|
|
|
<div key={goodsIndex} className={'flex items-center mb-2'}> |
|
|
|
|
|
<Image |
|
|
|
|
|
src={goods.image || '/default-goods.png'} |
|
|
|
|
|
width="50" |
|
|
|
|
|
height="50" |
|
|
|
|
|
lazyLoad={false} |
|
|
|
|
|
className={'rounded'} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
{/* 订单列表 */} |
|
|
|
|
|
{list.length > 0 && list?.map((item, index) => { |
|
|
|
|
|
return ( |
|
|
|
|
|
<Cell key={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={'text-gray-600 font-bold text-sm'} |
|
|
|
|
|
onClick={(e) => { |
|
|
|
|
|
e.stopPropagation(); |
|
|
|
|
|
copyText(`${item.orderNo}`) |
|
|
|
|
|
}}>{item.orderNo}</View> |
|
|
|
|
|
<View className={`${getOrderStatusColor(item)} font-medium`}>{getOrderStatusText(item)}</View> |
|
|
|
|
|
</View> |
|
|
|
|
|
<div |
|
|
|
|
|
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</div> |
|
|
|
|
|
|
|
|
|
|
|
{/* 商品信息 */} |
|
|
|
|
|
<div className={'goods-info'}> |
|
|
|
|
|
{item.orderGoods && item.orderGoods.length > 0 ? ( |
|
|
|
|
|
item.orderGoods.map((goods, goodsIndex) => ( |
|
|
|
|
|
<div key={goodsIndex} className={'flex items-center mb-2'}> |
|
|
|
|
|
<Image |
|
|
|
|
|
src={goods.image || '/default-goods.png'} |
|
|
|
|
|
width="50" |
|
|
|
|
|
height="50" |
|
|
|
|
|
lazyLoad={false} |
|
|
|
|
|
className={'rounded'} |
|
|
|
|
|
/> |
|
|
|
|
|
<div className={'ml-2 flex-1'}> |
|
|
|
|
|
<div className={'text-sm font-bold'}>{goods.goodsName}</div> |
|
|
|
|
|
{goods.spec && <div className={'text-gray-500 text-xs'}>规格:{goods.spec}</div>} |
|
|
|
|
|
<div className={'text-gray-500 text-xs'}>数量:{goods.totalNum}</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
<div className={'text-sm'}>¥{goods.price}</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
)) |
|
|
|
|
|
) : ( |
|
|
|
|
|
<div className={'flex items-center'}> |
|
|
|
|
|
<Avatar |
|
|
|
|
|
src='/default-goods.png' |
|
|
|
|
|
size={'50'} |
|
|
|
|
|
shape={'square'} |
|
|
/> |
|
|
/> |
|
|
<div className={'ml-2 flex-1'}> |
|
|
|
|
|
<div className={'text-sm font-bold'}>{goods.goodsName}</div> |
|
|
|
|
|
{goods.spec && <div className={'text-gray-500 text-xs'}>规格:{goods.spec}</div>} |
|
|
|
|
|
<div className={'text-gray-500 text-xs'}>数量:{goods.totalNum}</div> |
|
|
|
|
|
|
|
|
<div className={'ml-2'}> |
|
|
|
|
|
<div className={'text-sm'}>{item.title || '订单商品'}</div> |
|
|
|
|
|
<div className={'text-gray-400 text-xs'}>{item.totalNum}件商品</div> |
|
|
</div> |
|
|
</div> |
|
|
<div className={'text-sm'}>¥{goods.price}</div> |
|
|
|
|
|
</div> |
|
|
|
|
|
)) |
|
|
|
|
|
) : ( |
|
|
|
|
|
<div className={'flex items-center'}> |
|
|
|
|
|
<Avatar |
|
|
|
|
|
src='/default-goods.png' |
|
|
|
|
|
size={'50'} |
|
|
|
|
|
shape={'square'} |
|
|
|
|
|
/> |
|
|
|
|
|
<div className={'ml-2'}> |
|
|
|
|
|
<div className={'text-sm'}>{item.title || '订单商品'}</div> |
|
|
|
|
|
<div className={'text-gray-400 text-xs'}>{item.totalNum}件商品</div> |
|
|
|
|
|
</div> |
|
|
</div> |
|
|
</div> |
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className={'w-full text-right'}>实付金额:¥{item.payPrice}</div> |
|
|
|
|
|
|
|
|
|
|
|
{/* 操作按钮 */} |
|
|
|
|
|
<Space className={'btn flex justify-end'}> |
|
|
|
|
|
{/* 待付款状态:显示取消订单和立即支付 */} |
|
|
|
|
|
{(!item.payStatus) && item.orderStatus !== 2 && ( |
|
|
|
|
|
<Space> |
|
|
|
|
|
<Button size={'small'} onClick={(e) => {e.stopPropagation(); cancelOrder(item)}}>取消订单</Button> |
|
|
|
|
|
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); console.log('立即支付')}}>立即支付</Button> |
|
|
|
|
|
</Space> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* 待收货状态:显示确认收货 */} |
|
|
|
|
|
{item.deliveryStatus === 20 && ( |
|
|
|
|
|
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); confirmReceive(item)}}>确认收货</Button> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* 已完成状态:显示申请退款 */} |
|
|
|
|
|
{item.orderStatus === 1 && ( |
|
|
|
|
|
<Button size={'small'} onClick={(e) => {e.stopPropagation(); console.log('申请退款')}}>申请退款</Button> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* 退款相关状态的按钮可以在这里添加 */} |
|
|
|
|
|
|
|
|
)} |
|
|
|
|
|
</div> |
|
|
|
|
|
|
|
|
|
|
|
<div className={'w-full text-right'}>实付金额:¥{item.payPrice}</div> |
|
|
|
|
|
|
|
|
|
|
|
{/* 操作按钮 */} |
|
|
|
|
|
<Space className={'btn flex justify-end'}> |
|
|
|
|
|
{/* 待付款状态:显示取消订单和立即支付 */} |
|
|
|
|
|
{(!item.payStatus) && item.orderStatus !== 2 && ( |
|
|
|
|
|
<Space> |
|
|
|
|
|
<Button size={'small'} onClick={(e) => { |
|
|
|
|
|
e.stopPropagation(); |
|
|
|
|
|
cancelOrder(item) |
|
|
|
|
|
}}>取消订单</Button> |
|
|
|
|
|
<Button size={'small'} type="primary" onClick={(e) => { |
|
|
|
|
|
e.stopPropagation(); |
|
|
|
|
|
console.log('立即支付') |
|
|
|
|
|
}}>立即支付</Button> |
|
|
|
|
|
</Space> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* 待收货状态:显示确认收货 */} |
|
|
|
|
|
{item.deliveryStatus === 20 && ( |
|
|
|
|
|
<Button size={'small'} type="primary" onClick={(e) => { |
|
|
|
|
|
e.stopPropagation(); |
|
|
|
|
|
confirmReceive(item) |
|
|
|
|
|
}}>确认收货</Button> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* 已完成状态:显示申请退款 */} |
|
|
|
|
|
{item.orderStatus === 1 && ( |
|
|
|
|
|
<Button size={'small'} onClick={(e) => { |
|
|
|
|
|
e.stopPropagation(); |
|
|
|
|
|
console.log('申请退款') |
|
|
|
|
|
}}>申请退款</Button> |
|
|
|
|
|
)} |
|
|
|
|
|
{/* 退款相关状态的按钮可以在这里添加 */} |
|
|
|
|
|
</Space> |
|
|
</Space> |
|
|
</Space> |
|
|
</Space> |
|
|
|
|
|
</Cell> |
|
|
|
|
|
) |
|
|
|
|
|
|
|
|
</Cell> |
|
|
|
|
|
) |
|
|
})} |
|
|
})} |
|
|
</InfiniteLoading> |
|
|
</InfiniteLoading> |
|
|
)} |
|
|
)} |
|
|