* @created 2022-01-05 10:12:57 * @modified 2022-01-05 10:12:57 */ namespace Beike\Shop\Services; use Beike\Models\CartProduct; use Beike\Repositories\CartRepo; use Beike\Shop\Http\Resources\CartDetail; use Exception; class CartService { /** * 获取购物车商品列表 * * @param $customer * @param bool $selected * @return array */ public static function list($customer, bool $selected = false): array { $cartBuilder = CartRepo::allCartProductsBuilder($customer->id ?? 0); if ($selected) { $cartBuilder->where('selected', true); } $cartItems = $cartBuilder->get(); $cartItems = $cartItems->filter(function ($item) { $description = $item->sku->product->description ?? ''; $product = $item->product ?? null; if (empty($description) || empty($product)) { $item->delete(); } $cartQuantity = $item->quantity; $skuQuantity = $item->sku->quantity; if ($cartQuantity > $skuQuantity) { $item->quantity = $skuQuantity; $item->save(); } return $description && $product; }); $productQuantitySumList = []; foreach($cartItems as $item) { $productId = $item->product_id; $productQuantitySumList[$productId] = $productQuantitySumList[$productId] ?? 0; $productQuantitySumList[$productId] += $item->quantity; } foreach($cartItems as $item) { $productId = $item->product_id; $item->product_quantity_sum = $productQuantitySumList[$productId]; } return CartDetail::collection($cartItems)->jsonSerialize(); } /** * 创建购物车或者更新购物车数量 * @throws Exception */ public static function add($sku, int $quantity, $customer = null) { $customerId = $customer->id ?? 0; $productId = $sku->product_id; $skuId = $sku->id; if (empty($sku) || $quantity == 0) { return null; } if ($customerId) { $builder = CartProduct::query()->where('customer_id', $customerId); } else { $builder = CartProduct::query()->where('session_id', session()->getId()); } $cart = $builder->where('product_id', $productId) ->where('product_sku_id', $skuId) ->first(); if ($cart) { $cart->selected = true; $cart->increment('quantity', $quantity); } else { $cart = CartProduct::query()->create([ 'customer_id' => $customerId, 'session_id' => session()->getId(), 'product_id' => $productId, 'product_sku_id' => $skuId, 'quantity' => $quantity, 'selected' => true, ]); } $cartQuantity = $cart->quantity; $skuQuantity = $cart->sku->quantity; if ($cartQuantity > $skuQuantity) { throw new \Exception(trans('cart.stock_out')); } return $cart; } /** * 选择购物车商品 * * @param $customer * @param $cartIds */ public static function select($customer, $cartIds) { if ($customer) { $builder = CartProduct::query()->where('customer_id', $customer->id); } else { $builder = CartProduct::query()->where('session_id', session()->getId()); } $builder->update(['selected' => 0]); if (empty($cartIds)) { return; } $builder->whereIn('id', $cartIds) ->update(['selected' => 1]); } /** * 更新购物车数量 */ public static function updateQuantity($customer, $cartId, $quantity) { if (empty($cartId) || $quantity == 0) { return; } if ($customer) { $builder = CartProduct::query()->where('customer_id', $customer->id); } else { $builder = CartProduct::query()->where('session_id', session()->getId()); } $builder->where('id', $cartId) ->update(['quantity' => $quantity, 'selected' => 1]); } /** * 删除购物车商品 * * @param $customer * @param $cartId */ public static function delete($customer, $cartId) { if (empty($cartId)) { return; } $customerId = $customer->id ?? 0; if ($customerId) { $builder = CartProduct::query()->where('customer_id', $customerId); } else { $builder = CartProduct::query()->orWhere('session_id', session()->getId()); } $builder->where('id', $cartId) ->delete(); } /** * 获取购物车相关数据 * * @param array $carts * @return array */ public static function reloadData(array $carts = []): array { if (empty($carts)) { $carts = self::list(current_customer()); } $cartList = collect($carts)->where('selected', 1); $quantity = $cartList->sum('quantity'); $quantityAll = collect($carts)->sum('quantity'); $amount = $cartList->sum('subtotal'); $data = [ 'carts' => $carts, 'quantity' => $quantity, 'quantity_all' => $quantityAll, 'amount' => $amount, 'amount_format' => currency_format($amount), ]; return hook_filter('cart.data', $data); } }