优化下单流程
This commit is contained in:
@@ -8,7 +8,7 @@ import {View} from '@tarojs/components';
|
||||
import {listShopUserAddress} from "@/api/shop/shopUserAddress";
|
||||
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model";
|
||||
import './index.scss'
|
||||
import {useCart} from "@/hooks/useCart";
|
||||
import {useCart, CartItem} from "@/hooks/useCart";
|
||||
import Gap from "@/components/Gap";
|
||||
import {createOrder} from "@/api/shop/shopOrder";
|
||||
import {OrderCreateRequest} from "@/api/shop/shopOrder/model";
|
||||
@@ -19,11 +19,13 @@ const OrderConfirm = () => {
|
||||
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
||||
const [address, setAddress] = useState<ShopUserAddress>()
|
||||
const [payment, setPayment] = useState<Payment>()
|
||||
const [checkoutItems, setCheckoutItems] = useState<CartItem[]>([]);
|
||||
const router = Taro.getCurrentInstance().router;
|
||||
const goodsId = router?.params?.goodsId;
|
||||
|
||||
const {
|
||||
cartItems
|
||||
cartItems,
|
||||
removeFromCart
|
||||
} = useCart();
|
||||
|
||||
const reload = async () => {
|
||||
@@ -34,6 +36,25 @@ const OrderConfirm = () => {
|
||||
}
|
||||
}
|
||||
|
||||
// 加载结算商品数据
|
||||
const loadCheckoutItems = () => {
|
||||
try {
|
||||
const checkoutData = Taro.getStorageSync('checkout_items');
|
||||
if (checkoutData) {
|
||||
const items = JSON.parse(checkoutData) as CartItem[];
|
||||
setCheckoutItems(items);
|
||||
// 清除临时存储的数据
|
||||
Taro.removeStorageSync('checkout_items');
|
||||
} else {
|
||||
// 如果没有选中商品数据,使用全部购物车商品
|
||||
setCheckoutItems(cartItems);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('加载结算商品失败:', error);
|
||||
setCheckoutItems(cartItems);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 统一支付入口
|
||||
*/
|
||||
@@ -47,9 +68,9 @@ const OrderConfirm = () => {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!cartItems || cartItems.length === 0) {
|
||||
if (!checkoutItems || checkoutItems.length === 0) {
|
||||
Taro.showToast({
|
||||
title: '购物车为空',
|
||||
title: '没有要结算的商品',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
@@ -57,7 +78,7 @@ const OrderConfirm = () => {
|
||||
|
||||
// 构建订单数据
|
||||
const orderData = buildCartOrder(
|
||||
cartItems.map(item => ({
|
||||
checkoutItems.map(item => ({
|
||||
goodsId: item.goodsId!,
|
||||
quantity: item.quantity || 1
|
||||
})),
|
||||
@@ -72,7 +93,14 @@ const OrderConfirm = () => {
|
||||
const paymentType = payment?.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;
|
||||
|
||||
// 执行支付
|
||||
await PaymentHandler.pay(orderData, paymentType);
|
||||
await PaymentHandler.pay(orderData, paymentType, {
|
||||
onSuccess: () => {
|
||||
// 支付成功后,从购物车中移除已下单的商品
|
||||
checkoutItems.forEach(item => {
|
||||
removeFromCart(item.goodsId);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -83,12 +111,21 @@ const OrderConfirm = () => {
|
||||
console.error("Failed to fetch goods detail:", error);
|
||||
});
|
||||
}
|
||||
reload().then()
|
||||
}, [goodsId]);
|
||||
reload().then();
|
||||
loadCheckoutItems();
|
||||
}, [goodsId, cartItems]);
|
||||
|
||||
if (!goods) {
|
||||
return <div>加载中...</div>;
|
||||
}
|
||||
// 计算总价
|
||||
const getTotalPrice = () => {
|
||||
return checkoutItems.reduce((total, item) => {
|
||||
return total + (parseFloat(item.price) * item.quantity);
|
||||
}, 0).toFixed(2);
|
||||
};
|
||||
|
||||
// 计算商品总数量
|
||||
const getTotalQuantity = () => {
|
||||
return checkoutItems.reduce((total, item) => total + item.quantity, 0);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={'order-confirm-page'}>
|
||||
@@ -122,7 +159,7 @@ const OrderConfirm = () => {
|
||||
</CellGroup>
|
||||
|
||||
<CellGroup>
|
||||
{cartItems.map((goods, _) => (
|
||||
{checkoutItems.map((goods, _) => (
|
||||
<Cell key={goods.goodsId}>
|
||||
<Space>
|
||||
<Image src={goods.image} mode={'aspectFill'} style={{
|
||||
@@ -143,10 +180,10 @@ const OrderConfirm = () => {
|
||||
</CellGroup>
|
||||
|
||||
<CellGroup>
|
||||
<Cell title={'商品总价(共3件)'} extra={<View className={'font-medium'}>{'¥' + goods.price}</View>}/>
|
||||
<Cell title={`商品总价(共${getTotalQuantity()}件)`} extra={<View className={'font-medium'}>{'¥' + getTotalPrice()}</View>}/>
|
||||
<Cell title={'优惠券'} extra={(
|
||||
<View className={'flex justify-between items-center'}>
|
||||
<View className={'text-red-500 text-sm mr-1'}>-¥10.00</View>
|
||||
<View className={'text-red-500 text-sm mr-1'}>-¥0.00</View>
|
||||
<ArrowRight className={'text-gray-400'} size={14}/>
|
||||
</View>
|
||||
)}/>
|
||||
@@ -164,7 +201,7 @@ const OrderConfirm = () => {
|
||||
<View className={'btn-bar flex justify-between items-center'}>
|
||||
<div className={'flex justify-center items-center mx-4'}>
|
||||
<span className={'total-price text-sm text-gray-500'}>实付金额:</span>
|
||||
<span className={'text-red-500 text-xl font-bold'}>¥{goods.price}</span>
|
||||
<span className={'text-red-500 text-xl font-bold'}>¥{getTotalPrice()}</span>
|
||||
</div>
|
||||
<div className={'buy-btn mx-4'}>
|
||||
<Button type="success" size="large" onClick={onPay}>立即付款</Button>
|
||||
|
||||
@@ -3,20 +3,14 @@ import {Cell, CellGroup, Image, Space, Button} from '@nutui/nutui-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {ShopOrder} from "@/api/shop/shopOrder/model";
|
||||
import {getShopOrder} from "@/api/shop/shopOrder";
|
||||
import {listOrderGoods} from "@/api/system/orderGoods";
|
||||
import {OrderGoods} from "@/api/system/orderGoods/model";
|
||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||
import {listShopOrderGoods} from "@/api/shop/shopOrderGoods";
|
||||
import {ShopOrderGoods} from "@/api/shop/shopOrderGoods/model";
|
||||
import dayjs from "dayjs";
|
||||
import './index.scss'
|
||||
|
||||
interface OrderGoodsDetail extends OrderGoods {
|
||||
goodsName?: string;
|
||||
goodsImage?: string;
|
||||
}
|
||||
|
||||
const OrderDetail = () => {
|
||||
const [order, setOrder] = useState<ShopOrder | null>(null);
|
||||
const [orderGoodsList, setOrderGoodsList] = useState<OrderGoodsDetail[]>([]);
|
||||
const [orderGoodsList, setOrderGoodsList] = useState<ShopOrderGoods[]>([]);
|
||||
const router = Taro.getCurrentInstance().router;
|
||||
const orderId = router?.params?.orderId;
|
||||
|
||||
@@ -55,19 +49,9 @@ const OrderDetail = () => {
|
||||
setOrder(res);
|
||||
|
||||
// 获取订单商品列表
|
||||
const goodsRes = await listOrderGoods({ orderId: Number(orderId) });
|
||||
const goodsRes = await listShopOrderGoods({ orderId: Number(orderId) });
|
||||
if (goodsRes && goodsRes.length > 0) {
|
||||
const goodsDetailsPromises = goodsRes.map(async (item) => {
|
||||
console.log(item,'item.>>>')
|
||||
const shopGoods = await getShopGoods(Number(item.goodsId));
|
||||
return {
|
||||
...item,
|
||||
goodsName: shopGoods?.name,
|
||||
goodsImage: shopGoods?.image,
|
||||
};
|
||||
});
|
||||
const detailedGoodsList = await Promise.all(goodsDetailsPromises);
|
||||
setOrderGoodsList(detailedGoodsList);
|
||||
setOrderGoodsList(goodsRes);
|
||||
}
|
||||
}).catch(error => {
|
||||
console.error("Failed to fetch order detail:", error);
|
||||
@@ -91,11 +75,12 @@ const OrderDetail = () => {
|
||||
{orderGoodsList.map((item, index) => (
|
||||
<Cell key={index}>
|
||||
<div className={'flex items-center'}>
|
||||
<Image src={item.goodsImage} width="80" height="80" lazyLoad={false} />
|
||||
<Image src={item.image || '/default-goods.png'} width="80" height="80" lazyLoad={false} />
|
||||
<div className={'ml-2'}>
|
||||
<div className={'text-sm font-bold'}>{item.goodsName}</div>
|
||||
{item.spec && <div className={'text-gray-500 text-xs'}>规格:{item.spec}</div>}
|
||||
<div className={'text-gray-500 text-xs'}>数量:{item.totalNum}</div>
|
||||
<div className={'text-red-500 text-lg'}>¥{item.payPrice}</div>
|
||||
<div className={'text-red-500 text-lg'}>¥{item.price}</div>
|
||||
</div>
|
||||
</div>
|
||||
</Cell>
|
||||
|
||||
Reference in New Issue
Block a user