|
@@ -1,4 +1,4 @@
|
|
|
-import { useState, useEffect } from 'react'
|
|
|
|
|
|
|
+import React, { createContext, useContext, useState, useEffect, ReactNode } from 'react'
|
|
|
import Taro from '@tarojs/taro'
|
|
import Taro from '@tarojs/taro'
|
|
|
|
|
|
|
|
export interface CartItem {
|
|
export interface CartItem {
|
|
@@ -17,9 +17,22 @@ export interface CartState {
|
|
|
totalCount: number
|
|
totalCount: number
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+interface CartContextType {
|
|
|
|
|
+ cart: CartState
|
|
|
|
|
+ addToCart: (item: CartItem) => void
|
|
|
|
|
+ removeFromCart: (id: number) => void
|
|
|
|
|
+ updateQuantity: (id: number, quantity: number) => void
|
|
|
|
|
+ clearCart: () => void
|
|
|
|
|
+ isInCart: (id: number) => boolean
|
|
|
|
|
+ getItemQuantity: (id: number) => number
|
|
|
|
|
+ isLoading: boolean
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+const CartContext = createContext<CartContextType | undefined>(undefined)
|
|
|
|
|
+
|
|
|
const CART_STORAGE_KEY = 'mini_cart'
|
|
const CART_STORAGE_KEY = 'mini_cart'
|
|
|
|
|
|
|
|
-export const useCart = () => {
|
|
|
|
|
|
|
+export const CartProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
|
|
|
const [cart, setCart] = useState<CartState>({
|
|
const [cart, setCart] = useState<CartState>({
|
|
|
items: [],
|
|
items: [],
|
|
|
totalAmount: 0,
|
|
totalAmount: 0,
|
|
@@ -37,7 +50,7 @@ export const useCart = () => {
|
|
|
sum + (item.price * item.quantity), 0)
|
|
sum + (item.price * item.quantity), 0)
|
|
|
const totalCount = savedCart.items.reduce((sum: number, item: CartItem) =>
|
|
const totalCount = savedCart.items.reduce((sum: number, item: CartItem) =>
|
|
|
sum + item.quantity, 0)
|
|
sum + item.quantity, 0)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
setCart({
|
|
setCart({
|
|
|
items: savedCart.items,
|
|
items: savedCart.items,
|
|
|
totalAmount,
|
|
totalAmount,
|
|
@@ -58,15 +71,15 @@ export const useCart = () => {
|
|
|
const saveCart = (items: CartItem[]) => {
|
|
const saveCart = (items: CartItem[]) => {
|
|
|
const totalAmount = items.reduce((sum, item) => sum + (item.price * item.quantity), 0)
|
|
const totalAmount = items.reduce((sum, item) => sum + (item.price * item.quantity), 0)
|
|
|
const totalCount = items.reduce((sum, item) => sum + item.quantity, 0)
|
|
const totalCount = items.reduce((sum, item) => sum + item.quantity, 0)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const newCart = {
|
|
const newCart = {
|
|
|
items,
|
|
items,
|
|
|
totalAmount,
|
|
totalAmount,
|
|
|
totalCount
|
|
totalCount
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
setCart(newCart)
|
|
setCart(newCart)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
try {
|
|
try {
|
|
|
Taro.setStorageSync(CART_STORAGE_KEY, { items })
|
|
Taro.setStorageSync(CART_STORAGE_KEY, { items })
|
|
|
} catch (error) {
|
|
} catch (error) {
|
|
@@ -77,7 +90,7 @@ export const useCart = () => {
|
|
|
// 添加商品到购物车
|
|
// 添加商品到购物车
|
|
|
const addToCart = (item: CartItem) => {
|
|
const addToCart = (item: CartItem) => {
|
|
|
const existingItem = cart.items.find(cartItem => cartItem.id === item.id)
|
|
const existingItem = cart.items.find(cartItem => cartItem.id === item.id)
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (existingItem) {
|
|
if (existingItem) {
|
|
|
// 如果商品已存在,增加数量
|
|
// 如果商品已存在,增加数量
|
|
|
const newQuantity = Math.min(existingItem.quantity + item.quantity, item.stock)
|
|
const newQuantity = Math.min(existingItem.quantity + item.quantity, item.stock)
|
|
@@ -88,7 +101,7 @@ export const useCart = () => {
|
|
|
})
|
|
})
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const newItems = cart.items.map(cartItem =>
|
|
const newItems = cart.items.map(cartItem =>
|
|
|
cartItem.id === item.id
|
|
cartItem.id === item.id
|
|
|
? { ...cartItem, quantity: newQuantity }
|
|
? { ...cartItem, quantity: newQuantity }
|
|
@@ -108,7 +121,7 @@ export const useCart = () => {
|
|
|
})
|
|
})
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
saveCart([...cart.items, item])
|
|
saveCart([...cart.items, item])
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
@@ -127,12 +140,12 @@ export const useCart = () => {
|
|
|
const updateQuantity = (id: number, quantity: number) => {
|
|
const updateQuantity = (id: number, quantity: number) => {
|
|
|
const item = cart.items.find(item => item.id === id)
|
|
const item = cart.items.find(item => item.id === id)
|
|
|
if (!item) return
|
|
if (!item) return
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (quantity <= 0) {
|
|
if (quantity <= 0) {
|
|
|
removeFromCart(id)
|
|
removeFromCart(id)
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
if (quantity > item.stock) {
|
|
if (quantity > item.stock) {
|
|
|
Taro.showToast({
|
|
Taro.showToast({
|
|
|
title: '库存不足',
|
|
title: '库存不足',
|
|
@@ -140,7 +153,7 @@ export const useCart = () => {
|
|
|
})
|
|
})
|
|
|
return
|
|
return
|
|
|
}
|
|
}
|
|
|
-
|
|
|
|
|
|
|
+
|
|
|
const newItems = cart.items.map(item =>
|
|
const newItems = cart.items.map(item =>
|
|
|
item.id === id ? { ...item, quantity } : item
|
|
item.id === id ? { ...item, quantity } : item
|
|
|
)
|
|
)
|
|
@@ -167,7 +180,7 @@ export const useCart = () => {
|
|
|
return item ? item.quantity : 0
|
|
return item ? item.quantity : 0
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- return {
|
|
|
|
|
|
|
+ const value = {
|
|
|
cart,
|
|
cart,
|
|
|
addToCart,
|
|
addToCart,
|
|
|
removeFromCart,
|
|
removeFromCart,
|
|
@@ -177,4 +190,18 @@ export const useCart = () => {
|
|
|
getItemQuantity,
|
|
getItemQuantity,
|
|
|
isLoading
|
|
isLoading
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ return (
|
|
|
|
|
+ <CartContext.Provider value={value}>
|
|
|
|
|
+ {children}
|
|
|
|
|
+ </CartContext.Provider>
|
|
|
|
|
+ )
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+export const useCart = () => {
|
|
|
|
|
+ const context = useContext(CartContext)
|
|
|
|
|
+ if (context === undefined) {
|
|
|
|
|
+ throw new Error('useCart must be used within a CartProvider')
|
|
|
|
|
+ }
|
|
|
|
|
+ return context
|
|
|
}
|
|
}
|