101 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			101 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
import shop from '../../api/shop'
 | 
						|
import { CART, PRODUCTS } from '../mutation-types'
 | 
						|
 | 
						|
// initial state
 | 
						|
// shape: [{ id, quantity }]
 | 
						|
const state = {
 | 
						|
  // 购物车商品列表数据
 | 
						|
  items: [],
 | 
						|
  // 用于存放要加入购物车的商品跟数量的对应关系
 | 
						|
  preSelectProducts: {},
 | 
						|
  // 标记购买状态
 | 
						|
  checkoutStatus: null
 | 
						|
}
 | 
						|
 | 
						|
// getters
 | 
						|
const getters = {
 | 
						|
  cartProducts: (state, getters, rootState) => {
 | 
						|
    return state.items.map(({ id, quantity }) => {
 | 
						|
      const product = rootState.products.all.find(product => product.id === id)
 | 
						|
      return {
 | 
						|
        title: product.title,
 | 
						|
        price: product.price,
 | 
						|
        quantity
 | 
						|
      }
 | 
						|
    })
 | 
						|
  },
 | 
						|
 | 
						|
  cartTotalPrice: (state, getters) => {
 | 
						|
    return getters.cartProducts.reduce((total, product) => {
 | 
						|
      return total + product.price * product.quantity
 | 
						|
    }, 0)
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// actions
 | 
						|
const actions = {
 | 
						|
  checkout ({ commit, state }, products) {
 | 
						|
    const savedCartItems = [...state.items]
 | 
						|
    commit(CART.SET_CHECKOUT_STATUS, null)
 | 
						|
    // empty cart
 | 
						|
    commit(CART.SET_CART_ITEMS, { items: [] })
 | 
						|
    shop.buyProducts(
 | 
						|
      products,
 | 
						|
      () => commit(CART.SET_CHECKOUT_STATUS, 'successful'),
 | 
						|
      () => {
 | 
						|
        commit(CART.SET_CHECKOUT_STATUS, 'failed')
 | 
						|
        // rollback to the cart saved before sending the request
 | 
						|
        commit(CART.SET_CART_ITEMS, { items: savedCartItems })
 | 
						|
      }
 | 
						|
    )
 | 
						|
  },
 | 
						|
 | 
						|
  addProductToCart ({ state, commit }, { product, num} ) {
 | 
						|
    num = num < 1 ? 1 : num;
 | 
						|
    num = num > product.inventory ? product.inventory : num;
 | 
						|
    commit(CART.SET_CHECKOUT_STATUS, null)
 | 
						|
 | 
						|
    if (product.inventory > 0) {
 | 
						|
      const cartItem = state.items.find(item => item.id === product.id)
 | 
						|
      if (!cartItem) {
 | 
						|
        commit(CART.PUSH_PRODUCT_TO_CART, { id: product.id, num: num })
 | 
						|
      } else {
 | 
						|
        commit(CART.INCREMENT_ITEM_QUANTITY, { id: cartItem.id, num: num })
 | 
						|
      }
 | 
						|
      // remove 1 item from stock
 | 
						|
      commit(`products/${PRODUCTS.DECREMENT_PRODUCT_INVENTORY}`, { id: product.id, num: num }, { root: true })
 | 
						|
      state.preSelectProducts[product.id] = 1;
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
// mutations
 | 
						|
const mutations = {
 | 
						|
  [CART.PUSH_PRODUCT_TO_CART] (state, { id, num }) {
 | 
						|
    state.items.push({
 | 
						|
      id,
 | 
						|
      quantity: Number(num)
 | 
						|
    })
 | 
						|
  },
 | 
						|
 | 
						|
  [CART.INCREMENT_ITEM_QUANTITY] (state, { id, num }) {
 | 
						|
    const cartItem = state.items.find(item => item.id === id)
 | 
						|
    cartItem.quantity += Number(num)
 | 
						|
  },
 | 
						|
 | 
						|
  [CART.SET_CART_ITEMS] (state, { items }) {
 | 
						|
    state.items = items
 | 
						|
  },
 | 
						|
 | 
						|
  [CART.SET_CHECKOUT_STATUS] (state, status) {
 | 
						|
    state.checkoutStatus = status
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
export default {
 | 
						|
  namespaced: true,
 | 
						|
  state,
 | 
						|
  getters,
 | 
						|
  actions,
 | 
						|
  mutations
 | 
						|
} |