cart.js 4.18 KB
import { ref, provide, inject, watchEffect } from 'vue'
import { useRouter } from 'vue-router'

const CartSymbol = Symbol()

// 购物车模式配置
const CartMode = {
  SINGLE: 'single',  // 单一商品模式
  MULTIPLE: 'multiple'  // 多商品模式
}

export function provideCart(mode = CartMode.MULTIPLE) {
  const router = useRouter()
  const cartItems = ref([])
  const cartMode = ref(mode)

  // 从localStorage加载购物车数据
  try {
    const storedCart = localStorage.getItem('cart')
    if (storedCart) {
      cartItems.value = JSON.parse(storedCart)
    }
  } catch (error) {
    console.error('Failed to parse cart from localStorage:', error)
    localStorage.removeItem('cart')
  }

  // 监听购物车变化并保存到localStorage
  watchEffect(() => {
    localStorage.setItem('cart', JSON.stringify(cartItems.value))
  })

  // 添加商品到购物车
  function addToCart(item) {
    if (cartMode.value === CartMode.SINGLE) {
      // 单一商品模式:直接替换现有商品
      cartItems.value = [{ ...item, quantity: 1 }]
    } else {
      // 多商品模式:累加商品数量
      const existingItemIndex = cartItems.value.findIndex(
        i => i.id === item.id && i.type === item.type
      )

      if (existingItemIndex >= 0) {
        const updatedItems = [...cartItems.value]
        updatedItems[existingItemIndex] = {
          ...updatedItems[existingItemIndex],
          quantity: updatedItems[existingItemIndex].quantity + 1
        }
        cartItems.value = updatedItems
      } else {
        cartItems.value = [...cartItems.value, { ...item, quantity: 1 }]
      }
    }
  }

  // 从购物车移除商品
  function removeFromCart(itemId, itemType) {
    cartItems.value = cartItems.value.filter(
      item => !(item.id === itemId && item.type === itemType)
    )
  }

  // 更新商品数量
  function updateQuantity(itemId, itemType, quantity) {
    if (quantity < 1) return

    if (cartMode.value === CartMode.SINGLE) {
      // 单一商品模式:直接更新数量
      if (cartItems.value.length === 1) {
        cartItems.value = [{ ...cartItems.value[0], quantity }]
      }
    } else {
      // 多商品模式:更新指定商品数量
      cartItems.value = cartItems.value.map(item =>
        item.id === itemId && item.type === itemType
          ? { ...item, quantity }
          : item
      )
    }
  }

  // 清空购物车
  function clearCart() {
    cartItems.value = []
  }

  // 获取购物车商品总数
  function getItemCount() {
    return cartItems.value.reduce((total, item) => total + item.quantity, 0)
  }

  // 计算购物车总价
  function getTotalPrice() {
    return cartItems.value.reduce(
      (total, item) => total + item.price * item.quantity,
      0
    )
  }

  // 跳转到结账页面
  function proceedToCheckout() {
    if (cartItems.value.length > 0) {
      router.push('/checkout')
    }
  }

  // 处理结账流程
  function handleCheckout(userData) {
    // 构建订单数据
    const orderData = {
      items: cartItems.value.map(item => ({
        id: item.id,
        type: item.type,
        quantity: item.quantity,
        price: item.price,
        title: item.title
      })),
      totalAmount: getTotalPrice(),
      userData: userData,
      orderDate: new Date().toISOString()
    }

    // TODO: 替换为实际的API调用
    return new Promise((resolve) => {
      // 模拟API调用
      setTimeout(() => {
        // 在实际应用中,这里应该调用后端API
        console.warn('提交订单数据:', orderData)

        // 订单提交成功后清空购物车
        clearCart()

        // 返回订单ID
        resolve({
          success: true,
          orderId: 'ORD-' + Date.now(),
          orderData: orderData
        })
      }, 1500)
    })
  }

  const cart = {
    items: cartItems,
    mode: cartMode,
    addToCart,
    removeFromCart,
    updateQuantity,
    clearCart,
    getItemCount,
    getTotalPrice,
    proceedToCheckout,
    handleCheckout
  }

  provide(CartSymbol, cart)

  return cart
}

export function useCart() {
  const cart = inject(CartSymbol)
  if (!cart) {
    throw new Error('useCart() must be used within a component that has called provideCart()')
  }
  return cart
}