forked from gxwebsoft/mp-10550
优化下单流程
This commit is contained in:
@@ -20,9 +20,7 @@ export async function generateGoodsSku(data: ShopGoodsSpec) {
|
|||||||
export async function pageShopGoodsSku(params: ShopGoodsSkuParam) {
|
export async function pageShopGoodsSku(params: ShopGoodsSkuParam) {
|
||||||
const res = await request.get<ApiResult<PageResult<ShopGoodsSku>>>(
|
const res = await request.get<ApiResult<PageResult<ShopGoodsSku>>>(
|
||||||
'/shop/shop-goods-sku/page',
|
'/shop/shop-goods-sku/page',
|
||||||
{
|
params
|
||||||
params
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
return res.data;
|
return res.data;
|
||||||
@@ -36,9 +34,7 @@ export async function pageShopGoodsSku(params: ShopGoodsSkuParam) {
|
|||||||
export async function listShopGoodsSku(params?: ShopGoodsSkuParam) {
|
export async function listShopGoodsSku(params?: ShopGoodsSkuParam) {
|
||||||
const res = await request.get<ApiResult<ShopGoodsSku[]>>(
|
const res = await request.get<ApiResult<ShopGoodsSku[]>>(
|
||||||
'/shop/shop-goods-sku',
|
'/shop/shop-goods-sku',
|
||||||
{
|
params
|
||||||
params
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
if (res.code === 0 && res.data) {
|
if (res.code === 0 && res.data) {
|
||||||
return res.data;
|
return res.data;
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ export interface ShopOrder {
|
|||||||
// 代付支付方式,0余额支付, 1微信支付,102微信Native,2会员卡支付,3支付宝,4现金,5POS机,6VIP月卡,7VIP年卡,8VIP次卡,9IC月卡,10IC年卡,11IC次卡,12免费,13VIP充值卡,14IC充值卡,15积分支付,16VIP季卡,17IC季卡,18代付
|
// 代付支付方式,0余额支付, 1微信支付,102微信Native,2会员卡支付,3支付宝,4现金,5POS机,6VIP月卡,7VIP年卡,8VIP次卡,9IC月卡,10IC年卡,11IC次卡,12免费,13VIP充值卡,14IC充值卡,15积分支付,16VIP季卡,17IC季卡,18代付
|
||||||
friendPayType?: number;
|
friendPayType?: number;
|
||||||
// 0未付款,1已付款
|
// 0未付款,1已付款
|
||||||
payStatus?: number;
|
payStatus?: boolean;
|
||||||
// 0未使用,1已完成,2已取消,3取消中,4退款申请中,5退款被拒绝,6退款成功,7客户端申请退款
|
// 0未使用,1已完成,2已取消,3取消中,4退款申请中,5退款被拒绝,6退款成功,7客户端申请退款
|
||||||
orderStatus?: number;
|
orderStatus?: number;
|
||||||
// 发货状态(10未发货 20已发货 30部分发货)
|
// 发货状态(10未发货 20已发货 30部分发货)
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ export interface CartItem {
|
|||||||
image: string;
|
image: string;
|
||||||
quantity: number;
|
quantity: number;
|
||||||
addTime: number;
|
addTime: number;
|
||||||
|
skuId?: number;
|
||||||
|
specInfo?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 购物车Hook
|
// 购物车Hook
|
||||||
@@ -51,9 +53,15 @@ export const useCart = () => {
|
|||||||
name: string;
|
name: string;
|
||||||
price: string;
|
price: string;
|
||||||
image: string;
|
image: string;
|
||||||
|
skuId?: number;
|
||||||
|
specInfo?: string;
|
||||||
}, quantity: number = 1) => {
|
}, quantity: number = 1) => {
|
||||||
const newItems = [...cartItems];
|
const newItems = [...cartItems];
|
||||||
const existingItemIndex = newItems.findIndex(item => item.goodsId === goods.goodsId);
|
// 如果有SKU,需要根据goodsId和skuId来判断是否为同一商品
|
||||||
|
const existingItemIndex = newItems.findIndex(item =>
|
||||||
|
item.goodsId === goods.goodsId &&
|
||||||
|
(goods.skuId ? item.skuId === goods.skuId : !item.skuId)
|
||||||
|
);
|
||||||
|
|
||||||
if (existingItemIndex >= 0) {
|
if (existingItemIndex >= 0) {
|
||||||
// 如果商品已存在,增加数量
|
// 如果商品已存在,增加数量
|
||||||
@@ -66,7 +74,9 @@ export const useCart = () => {
|
|||||||
price: goods.price,
|
price: goods.price,
|
||||||
image: goods.image,
|
image: goods.image,
|
||||||
quantity,
|
quantity,
|
||||||
addTime: Date.now()
|
addTime: Date.now(),
|
||||||
|
skuId: goods.skuId,
|
||||||
|
specInfo: goods.specInfo
|
||||||
};
|
};
|
||||||
newItems.push(newItem);
|
newItems.push(newItem);
|
||||||
}
|
}
|
||||||
@@ -98,7 +108,7 @@ export const useCart = () => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const newItems = cartItems.map(item =>
|
const newItems = cartItems.map(item =>
|
||||||
item.goodsId === goodsId ? { ...item, quantity } : item
|
item.goodsId === goodsId ? { ...item, quantity } : item
|
||||||
);
|
);
|
||||||
setCartItems(newItems);
|
setCartItems(newItems);
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import {Avatar, Cell, Space, Tabs, Button, TabPane, Image, Toast} from '@nutui/nutui-react-taro'
|
import {Avatar, Cell, Space, Tabs, Button, TabPane, Image} from '@nutui/nutui-react-taro'
|
||||||
import {useEffect, useState, CSSProperties} from "react";
|
import {useEffect, useState, CSSProperties} from "react";
|
||||||
import Taro from '@tarojs/taro';
|
import Taro from '@tarojs/taro';
|
||||||
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
import {InfiniteLoading} from '@nutui/nutui-react-taro'
|
||||||
@@ -10,12 +10,13 @@ import {ShopOrderGoods} from "@/api/shop/shopOrderGoods/model";
|
|||||||
import {copyText} from "@/utils/common";
|
import {copyText} from "@/utils/common";
|
||||||
|
|
||||||
const InfiniteUlStyle: CSSProperties = {
|
const InfiniteUlStyle: CSSProperties = {
|
||||||
marginTop: '84px',
|
marginTop: '44px',
|
||||||
height: '82vh',
|
height: '82vh',
|
||||||
width: '100%',
|
width: '100%',
|
||||||
padding: '0',
|
padding: '0',
|
||||||
overflowY: 'auto',
|
overflowY: 'auto',
|
||||||
overflowX: 'hidden',
|
overflowX: 'hidden',
|
||||||
|
boxShadow: '0 0 10px rgba(0, 0, 0, 0.1)',
|
||||||
}
|
}
|
||||||
const tabs = [
|
const tabs = [
|
||||||
{
|
{
|
||||||
@@ -61,12 +62,11 @@ function OrderList(props: OrderListProps) {
|
|||||||
const [hasMore, setHasMore] = useState(true)
|
const [hasMore, setHasMore] = useState(true)
|
||||||
const [tapIndex, setTapIndex] = useState<string | number>('0')
|
const [tapIndex, setTapIndex] = useState<string | number>('0')
|
||||||
|
|
||||||
console.log(props.statusBarHeight, 'ppp')
|
|
||||||
|
|
||||||
// 获取订单状态文本
|
// 获取订单状态文本
|
||||||
const getOrderStatusText = (order: ShopOrder) => {
|
const getOrderStatusText = (order: ShopOrder) => {
|
||||||
if (order.payStatus === 0) return '待付款';
|
console.log(order,'order')
|
||||||
if (order.payStatus === 1 && order.deliveryStatus === 10) return '待发货';
|
if (!order.payStatus) return '待付款';
|
||||||
|
if (order.payStatus && 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 '已完成';
|
||||||
@@ -151,12 +151,15 @@ function OrderList(props: OrderListProps) {
|
|||||||
deliveryStatus: 30, // 已收货
|
deliveryStatus: 30, // 已收货
|
||||||
orderStatus: 1 // 已完成
|
orderStatus: 1 // 已完成
|
||||||
});
|
});
|
||||||
Toast.show('确认收货成功');
|
Taro.showToast({
|
||||||
|
title: '确认收货成功',
|
||||||
|
});
|
||||||
reload(true); // 重新加载列表
|
reload(true); // 重新加载列表
|
||||||
props.onReload?.(); // 通知父组件刷新
|
props.onReload?.(); // 通知父组件刷新
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('确认收货失败:', error);
|
Taro.showToast({
|
||||||
Toast.show('确认收货失败');
|
title: '确认收货失败',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -167,12 +170,16 @@ function OrderList(props: OrderListProps) {
|
|||||||
...order,
|
...order,
|
||||||
orderStatus: 2 // 已取消
|
orderStatus: 2 // 已取消
|
||||||
});
|
});
|
||||||
Toast.show('订单已取消');
|
Taro.showToast({
|
||||||
|
title: '订单已取消',
|
||||||
|
});
|
||||||
reload(true); // 重新加载列表
|
reload(true); // 重新加载列表
|
||||||
props.onReload?.(); // 通知父组件刷新
|
props.onReload?.(); // 通知父组件刷新
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('取消订单失败:', error);
|
console.error('取消订单失败:', error);
|
||||||
Toast.show('取消订单失败');
|
Taro.showToast({
|
||||||
|
title: '取消订单失败',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -185,8 +192,8 @@ function OrderList(props: OrderListProps) {
|
|||||||
<Tabs
|
<Tabs
|
||||||
align={'left'}
|
align={'left'}
|
||||||
className={'fixed left-0'}
|
className={'fixed left-0'}
|
||||||
style={{ top: '84px'}}
|
style={{ top: '44px'}}
|
||||||
tabStyle={{ backgroundColor: 'transparent'}}
|
tabStyle={{ backgroundColor: '#ffffff'}}
|
||||||
value={tapIndex}
|
value={tapIndex}
|
||||||
onChange={(paneKey) => {
|
onChange={(paneKey) => {
|
||||||
setTapIndex(paneKey)
|
setTapIndex(paneKey)
|
||||||
@@ -225,9 +232,9 @@ function OrderList(props: OrderListProps) {
|
|||||||
<Cell key={index} 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'}>
|
<Space direction={'vertical'} className={'w-full flex flex-col'}>
|
||||||
<div className={'order-no flex justify-between'}>
|
<div className={'order-no flex justify-between'}>
|
||||||
<span className={'text-gray-700 font-bold text-sm'}
|
<span className={'text-gray-600 font-bold text-sm'}
|
||||||
onClick={(e) => {e.stopPropagation(); copyText(`${item.orderNo}`)}}>{item.orderNo}</span>
|
onClick={(e) => {e.stopPropagation(); copyText(`${item.orderNo}`)}}>{item.orderNo}</span>
|
||||||
<span className={'text-orange-500'}>{getOrderStatusText(item)}</span>
|
<span className={'text-gray-600 font-medium'}>{getOrderStatusText(item)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</div>
|
className={'create-time text-gray-400 text-xs'}>{dayjs(item.createTime).format('YYYY年MM月DD日 HH:mm:ss')}</div>
|
||||||
@@ -249,7 +256,7 @@ function OrderList(props: OrderListProps) {
|
|||||||
{goods.spec && <div className={'text-gray-500 text-xs'}>规格:{goods.spec}</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={'text-gray-500 text-xs'}>数量:{goods.totalNum}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={'text-red-500 text-sm'}>¥{goods.price}</div>
|
<div className={'text-sm'}>¥{goods.price}</div>
|
||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
@@ -271,11 +278,11 @@ function OrderList(props: OrderListProps) {
|
|||||||
|
|
||||||
{/* 操作按钮 */}
|
{/* 操作按钮 */}
|
||||||
<Space className={'btn flex justify-end'}>
|
<Space className={'btn flex justify-end'}>
|
||||||
{item.payStatus === 0 && (
|
{item.payStatus && (
|
||||||
<>
|
<Space>
|
||||||
<Button size={'small'} onClick={(e) => {e.stopPropagation(); cancelOrder(item)}}>取消订单</Button>
|
<Button size={'small'} onClick={(e) => {e.stopPropagation(); cancelOrder(item)}}>取消订单</Button>
|
||||||
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); console.log('立即支付')}}>立即支付</Button>
|
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); console.log('立即支付')}}>立即支付</Button>
|
||||||
</>
|
</Space>
|
||||||
)}
|
)}
|
||||||
{item.deliveryStatus === 20 && (
|
{item.deliveryStatus === 20 && (
|
||||||
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); confirmReceive(item)}}>确认收货</Button>
|
<Button size={'small'} type="primary" onClick={(e) => {e.stopPropagation(); confirmReceive(item)}}>确认收货</Button>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
page {
|
page {
|
||||||
background: linear-gradient(to bottom, #e9fff2, #f9fafb);
|
background: linear-gradient(to bottom, #f3f3f3, #f9fafb);
|
||||||
background-size: 100%;
|
background-size: 100%;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ import {useState} from "react"; // 添加 useCallback 引入
|
|||||||
import Taro, {useDidShow} from '@tarojs/taro'
|
import Taro, {useDidShow} from '@tarojs/taro'
|
||||||
import {NavBar, Space, Empty, Button, ConfigProvider} from '@nutui/nutui-react-taro'
|
import {NavBar, Space, Empty, Button, ConfigProvider} from '@nutui/nutui-react-taro'
|
||||||
import {Search} from '@nutui/icons-react-taro'
|
import {Search} from '@nutui/icons-react-taro'
|
||||||
|
import { View } from '@tarojs/components';
|
||||||
import OrderList from "./components/OrderList";
|
import OrderList from "./components/OrderList";
|
||||||
import {ShopOrder} from "@/api/shop/shopOrder/model";
|
import {ShopOrder} from "@/api/shop/shopOrder/model";
|
||||||
import {pageShopOrder} from "@/api/shop/shopOrder";
|
import {pageShopOrder} from "@/api/shop/shopOrder";
|
||||||
@@ -25,19 +26,15 @@ function Order() {
|
|||||||
setStatusBarHeight(res.statusBarHeight)
|
setStatusBarHeight(res.statusBarHeight)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
// 设置导航栏背景色(含状态栏)
|
|
||||||
Taro.setNavigationBarColor({
|
|
||||||
backgroundColor: '#ffffff', // 状态栏+导航栏背景色
|
|
||||||
frontColor: 'black', // 状态栏文字颜色(仅支持 black/white)
|
|
||||||
});
|
|
||||||
reload().then()
|
reload().then()
|
||||||
}); // 新增: 添加滚动事件监听
|
}); // 新增: 添加滚动事件监听
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
<View style={{ height: `${statusBarHeight}px`, backgroundColor: '#ffffff'}}></View>
|
||||||
<NavBar
|
<NavBar
|
||||||
fixed={true}
|
fixed={true}
|
||||||
style={{marginTop: `${statusBarHeight}px`, backgroundColor: 'transparent'}}
|
style={{marginTop: `${statusBarHeight}px`, backgroundColor: '#ffffff'}}
|
||||||
left={
|
left={
|
||||||
<>
|
<>
|
||||||
<div className={'flex justify-between items-center w-full'}>
|
<div className={'flex justify-between items-center w-full'}>
|
||||||
|
|||||||
@@ -5,14 +5,25 @@ import Taro, {useShareAppMessage, useShareTimeline} from "@tarojs/taro";
|
|||||||
import {RichText, View} from '@tarojs/components'
|
import {RichText, View} from '@tarojs/components'
|
||||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||||
|
import {listShopGoodsSpec} from "@/api/shop/shopGoodsSpec";
|
||||||
|
import {ShopGoodsSpec} from "@/api/shop/shopGoodsSpec/model";
|
||||||
|
import {listShopGoodsSku} from "@/api/shop/shopGoodsSku";
|
||||||
|
import {ShopGoodsSku} from "@/api/shop/shopGoodsSku/model";
|
||||||
import {Swiper} from '@nutui/nutui-react-taro'
|
import {Swiper} from '@nutui/nutui-react-taro'
|
||||||
import navTo, {wxParse} from "@/utils/common";
|
import navTo, {wxParse} from "@/utils/common";
|
||||||
|
import SpecSelector from "@/components/SpecSelector";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
import {useCart} from "@/hooks/useCart";
|
import {useCart} from "@/hooks/useCart";
|
||||||
|
|
||||||
const GoodsDetail = () => {
|
const GoodsDetail = () => {
|
||||||
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
||||||
const [files, setFiles] = useState<any[]>([]);
|
const [files, setFiles] = useState<any[]>([]);
|
||||||
|
const [specs, setSpecs] = useState<ShopGoodsSpec[]>([]);
|
||||||
|
const [skus, setSkus] = useState<ShopGoodsSku[]>([]);
|
||||||
|
const [showSpecSelector, setShowSpecSelector] = useState(false);
|
||||||
|
const [specAction, setSpecAction] = useState<'cart' | 'buy'>('cart');
|
||||||
|
const [selectedSku, setSelectedSku] = useState<ShopGoodsSku | null>(null);
|
||||||
|
const [loading, setLoading] = useState(false);
|
||||||
const router = Taro.getCurrentInstance().router;
|
const router = Taro.getCurrentInstance().router;
|
||||||
const goodsId = router?.params?.id;
|
const goodsId = router?.params?.id;
|
||||||
|
|
||||||
@@ -31,6 +42,14 @@ const GoodsDetail = () => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 如果有规格,显示规格选择器
|
||||||
|
if (specs.length > 0) {
|
||||||
|
setSpecAction('cart');
|
||||||
|
setShowSpecSelector(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有规格,直接加入购物车
|
||||||
addToCart({
|
addToCart({
|
||||||
goodsId: goods.goodsId!,
|
goodsId: goods.goodsId!,
|
||||||
name: goods.name || '',
|
name: goods.name || '',
|
||||||
@@ -39,8 +58,61 @@ const GoodsDetail = () => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 处理立即购买
|
||||||
|
const handleBuyNow = () => {
|
||||||
|
if (!goods) return;
|
||||||
|
|
||||||
|
if (!Taro.getStorageSync('UserId')) {
|
||||||
|
return Taro.showToast({
|
||||||
|
title: '请先登录',
|
||||||
|
icon: 'none',
|
||||||
|
duration: 2000
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果有规格,显示规格选择器
|
||||||
|
if (specs.length > 0) {
|
||||||
|
setSpecAction('buy');
|
||||||
|
setShowSpecSelector(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 没有规格,直接购买
|
||||||
|
navTo(`/shop/orderConfirm/index?goodsId=${goods?.goodsId}`, true);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 规格选择确认回调
|
||||||
|
const handleSpecConfirm = (sku: ShopGoodsSku, quantity: number, action: 'cart' | 'buy') => {
|
||||||
|
setSelectedSku(sku);
|
||||||
|
setShowSpecSelector(false);
|
||||||
|
|
||||||
|
if (action === 'cart') {
|
||||||
|
// 加入购物车
|
||||||
|
addToCart({
|
||||||
|
goodsId: goods!.goodsId!,
|
||||||
|
skuId: sku.id,
|
||||||
|
name: goods!.name || '',
|
||||||
|
price: sku.price || goods!.price || '0',
|
||||||
|
image: goods!.image || '',
|
||||||
|
specInfo: sku.sku, // sku字段包含规格信息
|
||||||
|
}, quantity);
|
||||||
|
} else {
|
||||||
|
// 立即购买
|
||||||
|
const orderData = {
|
||||||
|
goodsId: goods!.goodsId!,
|
||||||
|
skuId: sku.id,
|
||||||
|
quantity,
|
||||||
|
price: sku.price || goods!.price || '0'
|
||||||
|
};
|
||||||
|
navTo(`/shop/orderConfirm/index?orderData=${encodeURIComponent(JSON.stringify(orderData))}`, true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (goodsId) {
|
if (goodsId) {
|
||||||
|
setLoading(true);
|
||||||
|
|
||||||
|
// 加载商品详情
|
||||||
getShopGoods(Number(goodsId))
|
getShopGoods(Number(goodsId))
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
// 处理富文本内容,去掉图片间距
|
// 处理富文本内容,去掉图片间距
|
||||||
@@ -52,10 +124,30 @@ const GoodsDetail = () => {
|
|||||||
const arr = JSON.parse(res.files);
|
const arr = JSON.parse(res.files);
|
||||||
arr.length > 0 && setFiles(arr);
|
arr.length > 0 && setFiles(arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.error("Failed to fetch goods detail:", error);
|
console.error("Failed to fetch goods detail:", error);
|
||||||
|
})
|
||||||
|
.finally(() => {
|
||||||
|
setLoading(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载商品规格
|
||||||
|
listShopGoodsSpec({ goodsId: Number(goodsId) } as any)
|
||||||
|
.then((data) => {
|
||||||
|
setSpecs(data || []);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Failed to fetch goods specs:", error);
|
||||||
|
});
|
||||||
|
|
||||||
|
// 加载商品SKU
|
||||||
|
listShopGoodsSku({ goodsId: Number(goodsId) } as any)
|
||||||
|
.then((data) => {
|
||||||
|
setSkus(data || []);
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
console.error("Failed to fetch goods skus:", error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [goodsId]);
|
}, [goodsId]);
|
||||||
@@ -94,7 +186,7 @@ const GoodsDetail = () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!goods) {
|
if (!goods || loading) {
|
||||||
return <div>加载中...</div>;
|
return <div>加载中...</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -209,11 +301,23 @@ const GoodsDetail = () => {
|
|||||||
onClick={() => handleAddToCart()}>加入购物车
|
onClick={() => handleAddToCart()}>加入购物车
|
||||||
</div>
|
</div>
|
||||||
<div className={'cart-buy pl-4 pr-5 text-sm'}
|
<div className={'cart-buy pl-4 pr-5 text-sm'}
|
||||||
onClick={() => navTo(`/shop/orderConfirm/index?goodsId=${goods?.goodsId}`, true)}>立即购买
|
onClick={() => handleBuyNow()}>立即购买
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</View>
|
</View>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* 规格选择器 */}
|
||||||
|
{showSpecSelector && (
|
||||||
|
<SpecSelector
|
||||||
|
goods={goods!}
|
||||||
|
specs={specs}
|
||||||
|
skus={skus}
|
||||||
|
action={specAction}
|
||||||
|
onConfirm={handleSpecConfirm}
|
||||||
|
onClose={() => setShowSpecSelector(false)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import {useEffect, useState} from "react";
|
import {useEffect, useState} from "react";
|
||||||
import {Image, Button, Cell, CellGroup, Input, Space, ActionSheet} from '@nutui/nutui-react-taro'
|
import {Image, Button, Cell, CellGroup, Input, Space, ActionSheet} from '@nutui/nutui-react-taro'
|
||||||
import {Location, ArrowRight} from '@nutui/icons-react-taro'
|
import {Location, ArrowRight} from '@nutui/icons-react-taro'
|
||||||
import Taro from '@tarojs/taro'
|
import Taro, {useDidShow} from '@tarojs/taro'
|
||||||
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
import {ShopGoods} from "@/api/shop/shopGoods/model";
|
||||||
import {getShopGoods} from "@/api/shop/shopGoods";
|
import {getShopGoods} from "@/api/shop/shopGoods";
|
||||||
import {View} from '@tarojs/components';
|
import {View} from '@tarojs/components';
|
||||||
@@ -87,6 +87,10 @@ const OrderConfirm = () => {
|
|||||||
await PaymentHandler.pay(orderData, paymentType);
|
await PaymentHandler.pay(orderData, paymentType);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
useDidShow(() => {
|
||||||
|
reload().then()
|
||||||
|
})
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (goodsId) {
|
if (goodsId) {
|
||||||
getShopGoods(Number(goodsId)).then(res => {
|
getShopGoods(Number(goodsId)).then(res => {
|
||||||
|
|||||||
@@ -254,7 +254,13 @@ const AddUserAddress = () => {
|
|||||||
width: '100%'
|
width: '100%'
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Button nativeType="submit" block type="info">
|
<Button
|
||||||
|
nativeType="submit"
|
||||||
|
type="success"
|
||||||
|
size="large"
|
||||||
|
className={'w-full'}
|
||||||
|
block
|
||||||
|
>
|
||||||
保存并使用
|
保存并使用
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -168,13 +168,17 @@ export function buildSingleGoodsOrder(
|
|||||||
deliveryType?: number;
|
deliveryType?: number;
|
||||||
couponId?: number;
|
couponId?: number;
|
||||||
selfTakeMerchantId?: number;
|
selfTakeMerchantId?: number;
|
||||||
|
skuId?: number;
|
||||||
|
specInfo?: string;
|
||||||
}
|
}
|
||||||
): OrderCreateRequest {
|
): OrderCreateRequest {
|
||||||
return {
|
return {
|
||||||
goodsItems: [
|
goodsItems: [
|
||||||
{
|
{
|
||||||
goodsId,
|
goodsId,
|
||||||
quantity
|
quantity,
|
||||||
|
skuId: options?.skuId,
|
||||||
|
specInfo: options?.specInfo
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
addressId,
|
addressId,
|
||||||
|
|||||||
Reference in New Issue
Block a user