forked from gxwebsoft/mp-10550
优化下单流程
This commit is contained in:
@@ -115,10 +115,17 @@ function Cart() {
|
||||
return;
|
||||
}
|
||||
|
||||
// 这里可以跳转到结算页面
|
||||
Taro.showToast({
|
||||
title: '跳转到结算页面',
|
||||
icon: 'success'
|
||||
// 获取选中的商品
|
||||
const selectedCartItems = cartItems.filter((item: CartItem) =>
|
||||
selectedItems.includes(item.goodsId)
|
||||
);
|
||||
|
||||
// 将选中的商品信息存储到本地,供结算页面使用
|
||||
Taro.setStorageSync('checkout_items', JSON.stringify(selectedCartItems));
|
||||
|
||||
// 跳转到购物车结算页面
|
||||
Taro.navigateTo({
|
||||
url: '/shop/orderConfirmCart/index'
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import {Avatar, Cell, Space, Tabs, Button, TabPane} from '@nutui/nutui-react-taro'
|
||||
import {Avatar, Cell, Space, Tabs, Button, TabPane, Image, Toast} from '@nutui/nutui-react-taro'
|
||||
import {useEffect, useState, CSSProperties} from "react";
|
||||
import Taro from '@tarojs/taro';
|
||||
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||
import dayjs from "dayjs";
|
||||
import {pageShopOrder} from "@/api/shop/shopOrder";
|
||||
import {pageShopOrder, updateShopOrder} from "@/api/shop/shopOrder";
|
||||
import {ShopOrder} from "@/api/shop/shopOrder/model";
|
||||
import {listShopOrderGoods} from "@/api/shop/shopOrderGoods";
|
||||
import {ShopOrderGoods} from "@/api/shop/shopOrderGoods/model";
|
||||
import {copyText} from "@/utils/common";
|
||||
|
||||
const InfiniteUlStyle: CSSProperties = {
|
||||
@@ -43,16 +45,42 @@ const tabs = [
|
||||
}
|
||||
]
|
||||
|
||||
function OrderList(props: any) {
|
||||
const [list, setList] = useState<ShopOrder[]>([])
|
||||
// 扩展订单接口,包含商品信息
|
||||
interface OrderWithGoods extends ShopOrder {
|
||||
orderGoods?: ShopOrderGoods[];
|
||||
}
|
||||
|
||||
interface OrderListProps {
|
||||
data: ShopOrder[];
|
||||
onReload?: () => void;
|
||||
}
|
||||
|
||||
function OrderList(props: OrderListProps) {
|
||||
const [list, setList] = useState<OrderWithGoods[]>([])
|
||||
const [page, setPage] = useState(1)
|
||||
const [hasMore, setHasMore] = useState(true)
|
||||
const [tapIndex, setTapIndex] = useState<string | number>('0')
|
||||
|
||||
console.log(props.statusBarHeight, 'ppp')
|
||||
|
||||
// 获取订单状态文本
|
||||
const getOrderStatusText = (order: ShopOrder) => {
|
||||
if (order.payStatus === 0) return '待付款';
|
||||
if (order.payStatus === 1 && order.deliveryStatus === 10) return '待发货';
|
||||
if (order.deliveryStatus === 20) return '待收货';
|
||||
if (order.deliveryStatus === 30) return '已收货';
|
||||
if (order.orderStatus === 1) return '已完成';
|
||||
if (order.orderStatus === 2) return '已取消';
|
||||
if (order.orderStatus === 4) return '退款申请中';
|
||||
if (order.orderStatus === 6) return '退款成功';
|
||||
return '未知状态';
|
||||
};
|
||||
|
||||
const getOrderStatusParams = (index: string | number) => {
|
||||
let params: { payStatus?: number; deliveryStatus?: number; orderStatus?: number } = {};
|
||||
let params: { payStatus?: number; deliveryStatus?: number; orderStatus?: number; userId?: number } = {};
|
||||
// 添加用户ID过滤
|
||||
params.userId = Taro.getStorageSync('UserId');
|
||||
|
||||
switch (index) {
|
||||
case '1': // 待付款
|
||||
params.payStatus = 0;
|
||||
@@ -77,13 +105,32 @@ function OrderList(props: any) {
|
||||
const reload = async (resetPage = false) => {
|
||||
const currentPage = resetPage ? 1 : page;
|
||||
const params = getOrderStatusParams(tapIndex);
|
||||
pageShopOrder({ page: currentPage, ...params }).then(res => {
|
||||
let newList: ShopOrder[] | undefined = [];
|
||||
pageShopOrder({ page: currentPage, ...params }).then(async res => {
|
||||
let newList: OrderWithGoods[] | undefined = [];
|
||||
if (res?.list && res?.list.length > 0) {
|
||||
newList = resetPage ? res.list : list?.concat(res.list);
|
||||
// 为每个订单获取商品信息
|
||||
const ordersWithGoods = await Promise.all(
|
||||
res.list.map(async (order) => {
|
||||
try {
|
||||
const orderGoods = await listShopOrderGoods({ orderId: order.orderId });
|
||||
return {
|
||||
...order,
|
||||
orderGoods: orderGoods || []
|
||||
};
|
||||
} catch (error) {
|
||||
console.error('获取订单商品失败:', error);
|
||||
return {
|
||||
...order,
|
||||
orderGoods: []
|
||||
};
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
newList = resetPage ? ordersWithGoods : list?.concat(ordersWithGoods);
|
||||
setHasMore(true);
|
||||
} else {
|
||||
newList = res?.list;
|
||||
newList = [];
|
||||
setHasMore(false);
|
||||
}
|
||||
setList(newList || []);
|
||||
@@ -96,6 +143,39 @@ function OrderList(props: any) {
|
||||
reload();
|
||||
};
|
||||
|
||||
// 确认收货
|
||||
const confirmReceive = async (order: ShopOrder) => {
|
||||
try {
|
||||
await updateShopOrder({
|
||||
...order,
|
||||
deliveryStatus: 30, // 已收货
|
||||
orderStatus: 1 // 已完成
|
||||
});
|
||||
Toast.show('确认收货成功');
|
||||
reload(true); // 重新加载列表
|
||||
props.onReload?.(); // 通知父组件刷新
|
||||
} catch (error) {
|
||||
console.error('确认收货失败:', error);
|
||||
Toast.show('确认收货失败');
|
||||
}
|
||||
};
|
||||
|
||||
// 取消订单
|
||||
const cancelOrder = async (order: ShopOrder) => {
|
||||
try {
|
||||
await updateShopOrder({
|
||||
...order,
|
||||
orderStatus: 2 // 已取消
|
||||
});
|
||||
Toast.show('订单已取消');
|
||||
reload(true); // 重新加载列表
|
||||
props.onReload?.(); // 通知父组件刷新
|
||||
} catch (error) {
|
||||
console.error('取消订单失败:', error);
|
||||
Toast.show('取消订单失败');
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
reload(true); // 首次加载或tab切换时重置页码
|
||||
}, [tapIndex]); // 监听tapIndex变化
|
||||
@@ -140,33 +220,69 @@ function OrderList(props: any) {
|
||||
</>
|
||||
}
|
||||
>
|
||||
{props.data?.map(item => {
|
||||
{list?.map((item, index) => {
|
||||
return (
|
||||
<Cell style={{padding: '16px'}} onClick={() => Taro.navigateTo({url: `/shop/orderDetail/index?orderId=${item.orderId}`})}>
|
||||
<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'}>
|
||||
<div className={'order-no flex justify-between'}>
|
||||
<span className={'text-gray-700 font-bold text-sm'}
|
||||
onClick={(e) => {e.stopPropagation(); copyText(`${item.orderNo}`)}}>{item.orderNo}</span>
|
||||
<span className={'text-orange-500'}>待付款</span> {/* 这里可以根据item.orderStatus显示不同的状态 */}
|
||||
<span className={'text-orange-500'}>{getOrderStatusText(item)}</span>
|
||||
</div>
|
||||
<div
|
||||
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</div>
|
||||
|
||||
{/* 商品信息 */}
|
||||
<div className={'goods-info'}>
|
||||
<div className={'flex items-center'}>
|
||||
{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-red-500 text-sm'}>¥{goods.price}</div>
|
||||
</div>
|
||||
))
|
||||
) : (
|
||||
<div className={'flex items-center'}>
|
||||
<Avatar
|
||||
src='34'
|
||||
size={'45'}
|
||||
src='/default-goods.png'
|
||||
size={'50'}
|
||||
shape={'square'}
|
||||
/>
|
||||
<div className={'ml-2'}>{item.realName}</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-gray-400 text-xs'}>{item.totalNum}件商品</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className={' w-full text-right'}>实付金额:¥{item.payPrice}</div>
|
||||
|
||||
<div className={'w-full text-right'}>实付金额:¥{item.payPrice}</div>
|
||||
|
||||
{/* 操作按钮 */}
|
||||
<Space className={'btn flex justify-end'}>
|
||||
<Button size={'small'}>发货</Button>
|
||||
{item.payStatus === 0 && (
|
||||
<>
|
||||
<Button size={'small'} onClick={(e) => {e.stopPropagation(); cancelOrder(item)}}>取消订单</Button>
|
||||
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); console.log('立即支付')}}>立即支付</Button>
|
||||
</>
|
||||
)}
|
||||
{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>
|
||||
</Cell>
|
||||
|
||||
@@ -78,7 +78,7 @@ function Order() {
|
||||
{/*订单列表*/}
|
||||
{
|
||||
list.length > 0 && (
|
||||
<OrderList data={list}/>
|
||||
<OrderList data={list} onReload={reload}/>
|
||||
)
|
||||
}
|
||||
</>
|
||||
|
||||
54
src/pages/order/test-order.tsx
Normal file
54
src/pages/order/test-order.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import React from 'react';
|
||||
import { Button, Space, Toast } from '@nutui/nutui-react-taro';
|
||||
import Taro from '@tarojs/taro';
|
||||
import { createOrder } from '@/api/shop/shopOrder';
|
||||
import { OrderCreateRequest } from '@/api/shop/shopOrder/model';
|
||||
|
||||
const TestOrder = () => {
|
||||
// 创建测试订单
|
||||
const createTestOrder = async () => {
|
||||
try {
|
||||
const orderData: OrderCreateRequest = {
|
||||
goodsItems: [
|
||||
{
|
||||
goodsId: 1,
|
||||
quantity: 2,
|
||||
skuId: 1,
|
||||
specInfo: '红色 L码'
|
||||
}
|
||||
],
|
||||
payType: 1, // 微信支付
|
||||
deliveryType: 0, // 快递
|
||||
comments: '测试订单'
|
||||
};
|
||||
|
||||
const result = await createOrder(orderData);
|
||||
console.log('订单创建成功:', result);
|
||||
Toast.show('测试订单创建成功');
|
||||
|
||||
// 跳转到订单列表
|
||||
setTimeout(() => {
|
||||
Taro.navigateTo({ url: '/pages/order/order' });
|
||||
}, 1000);
|
||||
} catch (error) {
|
||||
console.error('创建订单失败:', error);
|
||||
Toast.show('创建订单失败');
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ padding: '20px' }}>
|
||||
<h2>订单功能测试</h2>
|
||||
<Space direction="vertical">
|
||||
<Button type="primary" onClick={createTestOrder}>
|
||||
创建测试订单
|
||||
</Button>
|
||||
<Button onClick={() => Taro.navigateTo({ url: '/pages/order/order' })}>
|
||||
查看订单列表
|
||||
</Button>
|
||||
</Space>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TestOrder;
|
||||
Reference in New Issue
Block a user