forked from gxwebsoft/mp-10550
完成购物车功能
This commit is contained in:
@@ -128,15 +128,3 @@ export async function submit(data: UserVerify) {
|
|||||||
}
|
}
|
||||||
return Promise.reject(new Error(res.message));
|
return Promise.reject(new Error(res.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function myTenantList(params: any) {
|
|
||||||
const res = await request.get<ApiResult<UserVerify>>(
|
|
||||||
'http://127.0.0.1:8080/api/v1/tenants',
|
|
||||||
params
|
|
||||||
);
|
|
||||||
if (res.code === 0) {
|
|
||||||
return res.data;
|
|
||||||
}
|
|
||||||
return Promise.reject(new Error(res.message));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
60
src/components/CartIcon.tsx
Normal file
60
src/components/CartIcon.tsx
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { Badge } from "@nutui/nutui-react-taro";
|
||||||
|
import { Cart } from "@nutui/icons-react-taro";
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
import { useCart } from "@/hooks/useCart";
|
||||||
|
|
||||||
|
interface CartIconProps {
|
||||||
|
style?: React.CSSProperties;
|
||||||
|
className?: string;
|
||||||
|
size?: number;
|
||||||
|
showBadge?: boolean;
|
||||||
|
onClick?: () => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
const CartIcon: React.FC<CartIconProps> = ({
|
||||||
|
style,
|
||||||
|
className = '',
|
||||||
|
size = 16,
|
||||||
|
showBadge = true,
|
||||||
|
onClick
|
||||||
|
}) => {
|
||||||
|
const { cartCount } = useCart();
|
||||||
|
|
||||||
|
const handleClick = () => {
|
||||||
|
if (onClick) {
|
||||||
|
onClick();
|
||||||
|
} else {
|
||||||
|
// 默认跳转到购物车页面
|
||||||
|
Taro.switchTab({ url: '/pages/cart/cart' });
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (showBadge) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={className}
|
||||||
|
style={style}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<Badge value={cartCount} top="-2" right="2">
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
||||||
|
<Cart size={size} />
|
||||||
|
</div>
|
||||||
|
</Badge>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={className}
|
||||||
|
style={style}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
<Cart size={size} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default CartIcon;
|
||||||
151
src/hooks/useCart.ts
Normal file
151
src/hooks/useCart.ts
Normal file
@@ -0,0 +1,151 @@
|
|||||||
|
import { useState, useEffect } from 'react';
|
||||||
|
import Taro from '@tarojs/taro';
|
||||||
|
|
||||||
|
// 购物车商品接口
|
||||||
|
export interface CartItem {
|
||||||
|
goodsId: number;
|
||||||
|
name: string;
|
||||||
|
price: string;
|
||||||
|
image: string;
|
||||||
|
quantity: number;
|
||||||
|
addTime: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 购物车Hook
|
||||||
|
export const useCart = () => {
|
||||||
|
const [cartItems, setCartItems] = useState<CartItem[]>([]);
|
||||||
|
const [cartCount, setCartCount] = useState(0);
|
||||||
|
|
||||||
|
// 从本地存储加载购物车数据
|
||||||
|
const loadCartFromStorage = () => {
|
||||||
|
try {
|
||||||
|
const cartData = Taro.getStorageSync('cart_items');
|
||||||
|
if (cartData) {
|
||||||
|
const items = JSON.parse(cartData) as CartItem[];
|
||||||
|
setCartItems(items);
|
||||||
|
updateCartCount(items);
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('加载购物车数据失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 保存购物车数据到本地存储
|
||||||
|
const saveCartToStorage = (items: CartItem[]) => {
|
||||||
|
try {
|
||||||
|
Taro.setStorageSync('cart_items', JSON.stringify(items));
|
||||||
|
} catch (error) {
|
||||||
|
console.error('保存购物车数据失败:', error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新购物车数量
|
||||||
|
const updateCartCount = (items: CartItem[]) => {
|
||||||
|
const count = items.reduce((total, item) => total + item.quantity, 0);
|
||||||
|
setCartCount(count);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 添加商品到购物车
|
||||||
|
const addToCart = (goods: {
|
||||||
|
goodsId: number;
|
||||||
|
name: string;
|
||||||
|
price: string;
|
||||||
|
image: string;
|
||||||
|
}, quantity: number = 1) => {
|
||||||
|
const newItems = [...cartItems];
|
||||||
|
const existingItemIndex = newItems.findIndex(item => item.goodsId === goods.goodsId);
|
||||||
|
|
||||||
|
if (existingItemIndex >= 0) {
|
||||||
|
// 如果商品已存在,增加数量
|
||||||
|
newItems[existingItemIndex].quantity += quantity;
|
||||||
|
} else {
|
||||||
|
// 如果商品不存在,添加新商品
|
||||||
|
const newItem: CartItem = {
|
||||||
|
goodsId: goods.goodsId,
|
||||||
|
name: goods.name,
|
||||||
|
price: goods.price,
|
||||||
|
image: goods.image,
|
||||||
|
quantity,
|
||||||
|
addTime: Date.now()
|
||||||
|
};
|
||||||
|
newItems.push(newItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCartItems(newItems);
|
||||||
|
updateCartCount(newItems);
|
||||||
|
saveCartToStorage(newItems);
|
||||||
|
|
||||||
|
// 显示成功提示
|
||||||
|
Taro.showToast({
|
||||||
|
title: '加入购物车成功',
|
||||||
|
icon: 'success',
|
||||||
|
duration: 1500
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 从购物车移除商品
|
||||||
|
const removeFromCart = (goodsId: number) => {
|
||||||
|
const newItems = cartItems.filter(item => item.goodsId !== goodsId);
|
||||||
|
setCartItems(newItems);
|
||||||
|
updateCartCount(newItems);
|
||||||
|
saveCartToStorage(newItems);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新商品数量
|
||||||
|
const updateQuantity = (goodsId: number, quantity: number) => {
|
||||||
|
if (quantity <= 0) {
|
||||||
|
removeFromCart(goodsId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const newItems = cartItems.map(item =>
|
||||||
|
item.goodsId === goodsId ? { ...item, quantity } : item
|
||||||
|
);
|
||||||
|
setCartItems(newItems);
|
||||||
|
updateCartCount(newItems);
|
||||||
|
saveCartToStorage(newItems);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 清空购物车
|
||||||
|
const clearCart = () => {
|
||||||
|
setCartItems([]);
|
||||||
|
setCartCount(0);
|
||||||
|
Taro.removeStorageSync('cart_items');
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取购物车总价
|
||||||
|
const getTotalPrice = () => {
|
||||||
|
return cartItems.reduce((total, item) => {
|
||||||
|
return total + (parseFloat(item.price) * item.quantity);
|
||||||
|
}, 0).toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查商品是否在购物车中
|
||||||
|
const isInCart = (goodsId: number) => {
|
||||||
|
return cartItems.some(item => item.goodsId === goodsId);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 获取商品在购物车中的数量
|
||||||
|
const getItemQuantity = (goodsId: number) => {
|
||||||
|
const item = cartItems.find(item => item.goodsId === goodsId);
|
||||||
|
return item ? item.quantity : 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
// 初始化时加载购物车数据
|
||||||
|
useEffect(() => {
|
||||||
|
loadCartFromStorage();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return {
|
||||||
|
cartItems,
|
||||||
|
cartCount,
|
||||||
|
addToCart,
|
||||||
|
removeFromCart,
|
||||||
|
updateQuantity,
|
||||||
|
clearCart,
|
||||||
|
getTotalPrice,
|
||||||
|
isInCart,
|
||||||
|
getItemQuantity,
|
||||||
|
loadCartFromStorage
|
||||||
|
};
|
||||||
|
};
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
export default definePageConfig({
|
export default definePageConfig({
|
||||||
navigationBarTitleText: '购物车',
|
navigationBarTitleText: '购物车',
|
||||||
navigationBarTextStyle: 'black',
|
|
||||||
navigationStyle: 'custom'
|
navigationStyle: 'custom'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,21 +1,40 @@
|
|||||||
import {useEffect, useState} from "react"; // 添加 useCallback 引入
|
import {useEffect, useState} from "react";
|
||||||
import Taro, {useShareAppMessage, useShareTimeline} from '@tarojs/taro';
|
import Taro, {useShareAppMessage, useShareTimeline} from '@tarojs/taro';
|
||||||
import {Space, NavBar} from '@nutui/nutui-react-taro'
|
import {
|
||||||
import {Search, Received, Scan} from '@nutui/icons-react-taro'
|
NavBar,
|
||||||
import GoodsList from "@/components/GoodsList";
|
Checkbox,
|
||||||
|
Image,
|
||||||
|
InputNumber,
|
||||||
|
Button,
|
||||||
|
Empty,
|
||||||
|
Divider
|
||||||
|
} from '@nutui/nutui-react-taro';
|
||||||
|
import {ArrowLeft, Del, Shopping} from '@nutui/icons-react-taro';
|
||||||
|
import {View} from '@tarojs/components';
|
||||||
|
import {CartItem, useCart} from "@/hooks/useCart";
|
||||||
|
|
||||||
function Cart() {
|
function Cart() {
|
||||||
const [statusBarHeight, setStatusBarHeight] = useState<number>()
|
const [statusBarHeight, setStatusBarHeight] = useState<number>(0);
|
||||||
|
const [selectedItems, setSelectedItems] = useState<number[]>([]);
|
||||||
|
const [isAllSelected, setIsAllSelected] = useState(false);
|
||||||
|
|
||||||
|
const {
|
||||||
|
cartItems,
|
||||||
|
cartCount,
|
||||||
|
updateQuantity,
|
||||||
|
removeFromCart,
|
||||||
|
clearCart
|
||||||
|
} = useCart();
|
||||||
|
|
||||||
useShareTimeline(() => {
|
useShareTimeline(() => {
|
||||||
return {
|
return {
|
||||||
title: '注册即可开通 - webSoft云应用'
|
title: '购物车 - 云上商店'
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
useShareAppMessage(() => {
|
useShareAppMessage(() => {
|
||||||
return {
|
return {
|
||||||
title: '注册即可开通 - webSoft云应用',
|
title: '购物车 - 云上商店',
|
||||||
success: function (res) {
|
success: function (res) {
|
||||||
console.log('分享成功', res);
|
console.log('分享成功', res);
|
||||||
},
|
},
|
||||||
@@ -28,38 +47,235 @@ function Cart() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
Taro.getSystemInfo({
|
Taro.getSystemInfo({
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
setStatusBarHeight(res.statusBarHeight)
|
setStatusBarHeight(res.statusBarHeight || 0);
|
||||||
},
|
},
|
||||||
})
|
|
||||||
// 设置导航栏背景色(含状态栏)
|
|
||||||
Taro.setNavigationBarColor({
|
|
||||||
backgroundColor: '#ffffff', // 状态栏+导航栏背景色
|
|
||||||
frontColor: 'black', // 状态栏文字颜色(仅支持 black/white)
|
|
||||||
});
|
});
|
||||||
}, []); // 新增: 添加滚动事件监听
|
|
||||||
|
// 设置导航栏背景色
|
||||||
|
Taro.setNavigationBarColor({
|
||||||
|
backgroundColor: '#ffffff',
|
||||||
|
frontColor: 'black',
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// 处理单个商品选择
|
||||||
|
const handleItemSelect = (goodsId: number, checked: boolean) => {
|
||||||
|
if (checked) {
|
||||||
|
setSelectedItems([...selectedItems, goodsId]);
|
||||||
|
} else {
|
||||||
|
setSelectedItems(selectedItems.filter(id => id !== goodsId));
|
||||||
|
setIsAllSelected(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 处理全选
|
||||||
|
const handleSelectAll = (checked: boolean) => {
|
||||||
|
setIsAllSelected(checked);
|
||||||
|
if (checked) {
|
||||||
|
setSelectedItems(cartItems.map((item: CartItem) => item.goodsId));
|
||||||
|
} else {
|
||||||
|
setSelectedItems([]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 更新商品数量
|
||||||
|
const handleQuantityChange = (goodsId: number, value: number) => {
|
||||||
|
updateQuantity(goodsId, value);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 删除商品
|
||||||
|
const handleRemoveItem = (goodsId: number) => {
|
||||||
|
Taro.showModal({
|
||||||
|
title: '确认删除',
|
||||||
|
content: '确定要删除这个商品吗?',
|
||||||
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
removeFromCart(goodsId);
|
||||||
|
setSelectedItems(selectedItems.filter(id => id !== goodsId));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 计算选中商品的总价
|
||||||
|
const getSelectedTotalPrice = () => {
|
||||||
|
return cartItems
|
||||||
|
.filter((item: CartItem) => selectedItems.includes(item.goodsId))
|
||||||
|
.reduce((total: number, item: CartItem) => total + (parseFloat(item.price) * item.quantity), 0)
|
||||||
|
.toFixed(2);
|
||||||
|
};
|
||||||
|
|
||||||
|
// 去结算
|
||||||
|
const handleCheckout = () => {
|
||||||
|
if (selectedItems.length === 0) {
|
||||||
|
Taro.showToast({
|
||||||
|
title: '请选择要结算的商品',
|
||||||
|
icon: 'none'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 这里可以跳转到结算页面
|
||||||
|
Taro.showToast({
|
||||||
|
title: '跳转到结算页面',
|
||||||
|
icon: 'success'
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// 检查是否全选
|
||||||
|
useEffect(() => {
|
||||||
|
if (cartItems.length > 0 && selectedItems.length === cartItems.length) {
|
||||||
|
setIsAllSelected(true);
|
||||||
|
} else {
|
||||||
|
setIsAllSelected(false);
|
||||||
|
}
|
||||||
|
}, [selectedItems, cartItems]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
<View style={{backgroundColor: '#f6f6f6', height: `${statusBarHeight}px`}}
|
||||||
|
className="fixed z-10 top-0 w-full"></View>
|
||||||
<NavBar
|
<NavBar
|
||||||
fixed={true}
|
fixed={true}
|
||||||
style={{marginTop: `${statusBarHeight}px`}}
|
style={{marginTop: `${statusBarHeight}px`}}
|
||||||
onBackClick={() => {
|
left={<ArrowLeft onClick={() => Taro.navigateBack()}/>}
|
||||||
}}
|
right={
|
||||||
left={
|
cartItems.length > 0 && (
|
||||||
<>
|
<Button
|
||||||
<div className={'flex justify-between items-center w-full'}>
|
size="small"
|
||||||
<Space>
|
type="primary"
|
||||||
<Search size={18} className={'mx-1'}/>
|
fill="none"
|
||||||
<Received size={18} className={'mx-1'}/>
|
onClick={() => {
|
||||||
<Scan size={18} className={'mx-1'}/>
|
Taro.showModal({
|
||||||
</Space>
|
title: '确认清空',
|
||||||
</div>
|
content: '确定要清空购物车吗?',
|
||||||
</>
|
success: (res) => {
|
||||||
|
if (res.confirm) {
|
||||||
|
clearCart();
|
||||||
|
setSelectedItems([]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
</Button>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<span>商品</span>
|
<span className="text-lg">购物车({cartCount})</span>
|
||||||
</NavBar>
|
</NavBar>
|
||||||
<GoodsList/>
|
|
||||||
|
{/* 购物车内容 */}
|
||||||
|
<View className="pt-24">
|
||||||
|
{cartItems.length === 0 ? (
|
||||||
|
// 空购物车
|
||||||
|
<View className="flex flex-col items-center justify-center h-96">
|
||||||
|
<Empty
|
||||||
|
image={<Shopping size={80}/>}
|
||||||
|
description="购物车空空如也"
|
||||||
|
>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="small"
|
||||||
|
onClick={() => Taro.switchTab({url: '/pages/index/index'})}
|
||||||
|
>
|
||||||
|
去逛逛
|
||||||
|
</Button>
|
||||||
|
</Empty>
|
||||||
|
</View>
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
{/* 商品列表 */}
|
||||||
|
<View className="bg-white">
|
||||||
|
{cartItems.map((item: CartItem, index: number) => (
|
||||||
|
<View key={item.goodsId}>
|
||||||
|
<View className="bg-white px-4 py-3 flex items-center gap-3">
|
||||||
|
{/* 选择框 */}
|
||||||
|
<Checkbox
|
||||||
|
checked={selectedItems.includes(item.goodsId)}
|
||||||
|
onChange={(checked) => handleItemSelect(item.goodsId, checked)}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 商品图片 */}
|
||||||
|
<Image
|
||||||
|
src={item.image}
|
||||||
|
width="80"
|
||||||
|
height="80"
|
||||||
|
radius="8"
|
||||||
|
className="flex-shrink-0"
|
||||||
|
/>
|
||||||
|
|
||||||
|
{/* 商品信息 */}
|
||||||
|
<View className="flex-1 min-w-0">
|
||||||
|
<View className="text-lg font-bold text-gray-900 truncate mb-1">
|
||||||
|
{item.name}
|
||||||
|
</View>
|
||||||
|
<View className="flex items-center justify-between">
|
||||||
|
<View className={'flex text-red-500 text-xl items-baseline'}>
|
||||||
|
<span className={'text-xs'}>¥</span>
|
||||||
|
<span className={'font-bold text-lg'}>{item.price}</span>
|
||||||
|
</View>
|
||||||
|
<View className="flex items-center gap-2">
|
||||||
|
<InputNumber
|
||||||
|
value={item.quantity}
|
||||||
|
min={1}
|
||||||
|
max={99}
|
||||||
|
onChange={(value) => handleQuantityChange(item.goodsId, Number(value))}
|
||||||
|
className="w-24"
|
||||||
|
/>
|
||||||
|
<Del className={'text-red-500'} size={16} onClick={() => handleRemoveItem(item.goodsId)}/>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
{index < cartItems.length - 1 && <Divider/>}
|
||||||
|
</View>
|
||||||
|
))}
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 底部结算栏 */}
|
||||||
|
<View
|
||||||
|
className="fixed z-50 bottom-0 left-0 right-0 bg-white border-t border-gray-200 px-4 py-3 safe-area-bottom">
|
||||||
|
<View className="flex items-center justify-between">
|
||||||
|
<View className="flex items-center gap-3">
|
||||||
|
<Checkbox
|
||||||
|
checked={isAllSelected}
|
||||||
|
onChange={handleSelectAll}
|
||||||
|
>
|
||||||
|
全选
|
||||||
|
</Checkbox>
|
||||||
|
<View className="text-sm text-gray-600">
|
||||||
|
已选 {selectedItems.length} 件
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
<View className="flex items-center gap-4">
|
||||||
|
<View className="text-right">
|
||||||
|
<View className="text-xs text-gray-500">合计:</View>
|
||||||
|
<div className={'flex text-red-500 text-xl items-baseline'}>
|
||||||
|
<span className={'text-xs'}>¥</span>
|
||||||
|
<span className={'font-bold text-lg'}>{getSelectedTotalPrice()}</span>
|
||||||
|
</div>
|
||||||
|
</View>
|
||||||
|
<Button
|
||||||
|
type="primary"
|
||||||
|
size="large"
|
||||||
|
disabled={selectedItems.length === 0}
|
||||||
|
onClick={handleCheckout}
|
||||||
|
className="px-6"
|
||||||
|
>
|
||||||
|
结算({selectedItems.length})
|
||||||
|
</Button>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
</View>
|
||||||
|
|
||||||
|
{/* 底部安全区域占位 */}
|
||||||
|
<View className="h-20"></View>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
</View>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import {Popup, Avatar, NavBar} from '@nutui/nutui-react-taro'
|
|||||||
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
import {getSiteInfo, getUserInfo, getWxOpenId} from "@/api/layout";
|
||||||
import {TenantId} from "@/utils/config";
|
import {TenantId} from "@/utils/config";
|
||||||
import {getOrganization} from "@/api/system/organization";
|
import {getOrganization} from "@/api/system/organization";
|
||||||
import {myTenantList, myUserVerify} from "@/api/system/userVerify";
|
import {myUserVerify} from "@/api/system/userVerify";
|
||||||
import {CmsWebsite} from "@/api/cms/cmsWebsite/model";
|
import {CmsWebsite} from "@/api/cms/cmsWebsite/model";
|
||||||
import {User} from "@/api/system/user/model";
|
import {User} from "@/api/system/user/model";
|
||||||
import './Header.scss';
|
import './Header.scss';
|
||||||
@@ -84,10 +84,6 @@ const Header = () => {
|
|||||||
Taro.setStorageSync('RealName', data.realName)
|
Taro.setStorageSync('RealName', data.realName)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
//
|
|
||||||
myTenantList({page: 2, page_size: 50}).then(res => {
|
|
||||||
console.log(res, '...res...lei')
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 获取用户手机号 */
|
/* 获取用户手机号 */
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ function MySearch(props) {
|
|||||||
display: 'flex',
|
display: 'flex',
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
background: '#ffffff',
|
background: '#ffffff',
|
||||||
padding: '0 7px',
|
padding: '0 5px',
|
||||||
borderRadius: '20px',
|
borderRadius: '20px',
|
||||||
marginTop: '100px',
|
marginTop: '100px',
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import {getShopGoods} from "@/api/shop/shopGoods";
|
|||||||
import {Swiper} from '@nutui/nutui-react-taro'
|
import {Swiper} from '@nutui/nutui-react-taro'
|
||||||
import {wxParse} from "@/utils/common";
|
import {wxParse} from "@/utils/common";
|
||||||
import "./index.scss";
|
import "./index.scss";
|
||||||
|
import {useCart} from "@/hooks/useCart";
|
||||||
|
|
||||||
const GoodsDetail = () => {
|
const GoodsDetail = () => {
|
||||||
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
const [goods, setGoods] = useState<ShopGoods | null>(null);
|
||||||
@@ -15,6 +16,21 @@ const GoodsDetail = () => {
|
|||||||
const router = Taro.getCurrentInstance().router;
|
const router = Taro.getCurrentInstance().router;
|
||||||
const goodsId = router?.params?.id;
|
const goodsId = router?.params?.id;
|
||||||
|
|
||||||
|
// 使用购物车Hook
|
||||||
|
const { cartCount, addToCart } = useCart();
|
||||||
|
|
||||||
|
// 处理加入购物车
|
||||||
|
const handleAddToCart = () => {
|
||||||
|
if (!goods) return;
|
||||||
|
|
||||||
|
addToCart({
|
||||||
|
goodsId: goods.goodsId!,
|
||||||
|
name: goods.name || '',
|
||||||
|
price: goods.price || '0',
|
||||||
|
image: goods.image || ''
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (goodsId) {
|
if (goodsId) {
|
||||||
getShopGoods(Number(goodsId))
|
getShopGoods(Number(goodsId))
|
||||||
@@ -100,8 +116,9 @@ const GoodsDetail = () => {
|
|||||||
height: "32px",
|
height: "32px",
|
||||||
top: "50px",
|
top: "50px",
|
||||||
right: "110px",
|
right: "110px",
|
||||||
}}>
|
}}
|
||||||
<Badge value={8} top="-2" right="2">
|
onClick={() => Taro.navigateTo({url: '/pages/cart/cart'})}>
|
||||||
|
<Badge value={cartCount} top="-2" right="2">
|
||||||
<div style={{display: 'flex', alignItems: 'center'}}>
|
<div style={{display: 'flex', alignItems: 'center'}}>
|
||||||
<Cart size={16}/>
|
<Cart size={16}/>
|
||||||
</div>
|
</div>
|
||||||
@@ -181,7 +198,7 @@ const GoodsDetail = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className={'buy-btn mx-4'}>
|
<div className={'buy-btn mx-4'}>
|
||||||
<div className={'cart-add px-4 text-sm'}
|
<div className={'cart-add px-4 text-sm'}
|
||||||
onClick={() => Taro.showToast({title: '加入购物车成功', icon: 'success'})}>加入购物车
|
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={() => Taro.navigateTo({url: '/shop/orderConfirm/index'})}>立即购买
|
onClick={() => Taro.navigateTo({url: '/shop/orderConfirm/index'})}>立即购买
|
||||||
|
|||||||
@@ -25,7 +25,8 @@
|
|||||||
"@/components/*": ["./src/components/*"],
|
"@/components/*": ["./src/components/*"],
|
||||||
"@/utils/*": ["./src/utils/*"],
|
"@/utils/*": ["./src/utils/*"],
|
||||||
"@/assets/*": ["./src/assets/*"],
|
"@/assets/*": ["./src/assets/*"],
|
||||||
"@/api/*": ["./src/api/*"]
|
"@/api/*": ["./src/api/*"],
|
||||||
|
"@/hooks/*": ["./src/hooks/*"]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"include": ["./src", "./types"],
|
"include": ["./src", "./types"],
|
||||||
|
|||||||
Reference in New Issue
Block a user