feat(pages): 添加多个页面配置和功能模块
- 新增 .editorconfig、.eslintrc、.gitignore 配置文件 - 添加管理员文章管理页面配置和功能实现 - 添加经销商申请注册页面配置和功能实现 - 添加经销商银行卡管理页面配置和功能实现 - 添加经销商客户管理页面配置和功能实现 - 添加用户地址管理页面配置和功能实现 - 添加用户聊天消息页面配置和功能实现 - 添加用户礼品管理页面配置和功能实现
This commit is contained in:
213
src/shop/orderConfirmCart/index.tsx
Normal file
213
src/shop/orderConfirmCart/index.tsx
Normal file
@@ -0,0 +1,213 @@
|
||||
import {useEffect, useState} from "react";
|
||||
import {Image, Button, Cell, CellGroup, Input, Space} from '@nutui/nutui-react-taro'
|
||||
import {Location, ArrowRight} from '@nutui/icons-react-taro'
|
||||
import Taro from '@tarojs/taro'
|
||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||
import {View} from '@tarojs/components';
|
||||
import {listShopUserAddress} from "@/api/shop/shopUserAddress";
|
||||
import {ShopUserAddress} from "@/api/shop/shopUserAddress/model";
|
||||
import './index.scss'
|
||||
import {useCart, CartItem} from "@/hooks/useCart";
|
||||
import Gap from "@/components/Gap";
|
||||
import {Payment} from "@/api/system/payment/model";
|
||||
import {PaymentHandler, PaymentType, buildCartOrder} from "@/utils/payment";
|
||||
|
||||
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,
|
||||
removeFromCart
|
||||
} = useCart();
|
||||
|
||||
console.log(goods, 'goods>>>>')
|
||||
console.log(setPayment,'setPayment>>>')
|
||||
const reload = async () => {
|
||||
const address = await listShopUserAddress({isDefault: true});
|
||||
if (address.length > 0) {
|
||||
console.log(address, '111')
|
||||
setAddress(address[0])
|
||||
}
|
||||
}
|
||||
|
||||
// 加载结算商品数据
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 统一支付入口
|
||||
*/
|
||||
const onPay = async () => {
|
||||
// 基础校验
|
||||
if (!address) {
|
||||
Taro.showToast({
|
||||
title: '请选择收货地址',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!checkoutItems || checkoutItems.length === 0) {
|
||||
Taro.showToast({
|
||||
title: '没有要结算的商品',
|
||||
icon: 'error'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 构建订单数据
|
||||
const orderData = buildCartOrder(
|
||||
checkoutItems.map(item => ({
|
||||
goodsId: item.goodsId!,
|
||||
quantity: item.quantity || 1
|
||||
})),
|
||||
address.id,
|
||||
{
|
||||
comments: '购物车下单',
|
||||
deliveryType: 0
|
||||
}
|
||||
);
|
||||
|
||||
// 根据支付方式选择支付类型,默认微信支付
|
||||
const paymentType = payment?.type === 0 ? PaymentType.BALANCE : PaymentType.WECHAT;
|
||||
|
||||
// 执行支付
|
||||
await PaymentHandler.pay(orderData, paymentType, {
|
||||
onSuccess: () => {
|
||||
// 支付成功后,从购物车中移除已下单的商品
|
||||
checkoutItems.forEach(item => {
|
||||
removeFromCart(item.goodsId);
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (goodsId) {
|
||||
getShopGoods(Number(goodsId)).then(res => {
|
||||
setGoods(res);
|
||||
}).catch(error => {
|
||||
console.error("Failed to fetch goods detail:", error);
|
||||
});
|
||||
}
|
||||
reload().then();
|
||||
loadCheckoutItems();
|
||||
}, [goodsId, cartItems]);
|
||||
|
||||
// 计算总价
|
||||
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'}>
|
||||
<CellGroup>
|
||||
{
|
||||
address && (
|
||||
<Cell className={'address-bottom-line'} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
|
||||
<Space>
|
||||
<Location/>
|
||||
<View className={'flex flex-col w-full justify-between items-start'}>
|
||||
<Space className={'flex flex-row w-full font-medium'}>
|
||||
<View className={'flex-wrap text-nowrap whitespace-nowrap'}>送至</View>
|
||||
<View style={{width: '64%'}}
|
||||
className={'line-clamp-1 relative'}>{address.province} {address.city} {address.region} {address.address}
|
||||
</View>
|
||||
</Space>
|
||||
<View className={'pt-1 pb-3 text-gray-500'}>{address.name} {address.phone}</View>
|
||||
</View>
|
||||
</Space>
|
||||
</Cell>
|
||||
)
|
||||
}
|
||||
{!address && (
|
||||
<Cell className={''} onClick={() => Taro.navigateTo({url: '/user/address/index'})}>
|
||||
<Space>
|
||||
<Location/>
|
||||
添加收货地址
|
||||
</Space>
|
||||
</Cell>
|
||||
)}
|
||||
</CellGroup>
|
||||
|
||||
<CellGroup>
|
||||
{checkoutItems.map((goods, _) => (
|
||||
<Cell key={goods.goodsId}>
|
||||
<Space>
|
||||
<Image src={goods.image} mode={'aspectFill'} style={{
|
||||
width: '80px',
|
||||
height: '80px',
|
||||
}} lazyLoad={false}/>
|
||||
<View className={'flex flex-col'}>
|
||||
<View className={'font-medium w-full'}>{goods.name}</View>
|
||||
<View className={'number text-gray-400 text-sm py-2'}>80g/袋</View>
|
||||
<Space className={'flex justify-start items-center'}>
|
||||
<View className={'text-red-500'}>¥{goods.price}</View>
|
||||
<View className={'text-gray-500 text-sm'}>x {goods.quantity}</View>
|
||||
</Space>
|
||||
</View>
|
||||
</Space>
|
||||
</Cell>
|
||||
))}
|
||||
</CellGroup>
|
||||
|
||||
<CellGroup>
|
||||
<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'}>-¥0.00</View>
|
||||
<ArrowRight className={'text-gray-400'} size={14}/>
|
||||
</View>
|
||||
)}/>
|
||||
{/*<Cell title={'配送费'} extra={'¥' + 10}/>*/}
|
||||
<Cell title={'订单备注'} extra={(
|
||||
<Input placeholder={'选填,请先和商家协商一致'} style={{ padding: '0'}}/>
|
||||
)}/>
|
||||
</CellGroup>
|
||||
|
||||
<Gap height={50} />
|
||||
|
||||
<div className={'fixed z-50 bg-white w-full bottom-0 left-0 pt-4 pb-10 border-t border-gray-200'}>
|
||||
<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'}>¥{getTotalPrice()}</span>
|
||||
</div>
|
||||
<div className={'buy-btn mx-4'}>
|
||||
<Button type="success" size="large" onClick={onPay}>立即付款</Button>
|
||||
</div>
|
||||
</View>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default OrderConfirm;
|
||||
Reference in New Issue
Block a user