filled('part') ? $this->filterProductsByPart($request) : $this->filterProducts($request); return ProductSkuSimpleResource::collection($skus); } /** * 商品详情 * * @param int $id * @param \Illuminate\Http\Request $request * @return \Illuminate\Http\JsonResponse */ public function show($id, Request $request) { $sku = ProductSku::findOrFail($id); if (! $sku->isOnline()) { return response()->json([ 'spu_specs' => [], 'sku' => array_merge(ProduckSkuResource::make($sku)->resolve(), [ 'status' => ProductSku::STATUS_OFFLINE, ]), ]); } $spu = ProductSpu::with('specs')->findOrFail($sku->spu_id); // 如果商品已失效 if (! $spu->isValidProductSku($sku)) { return response()->json([ 'spu_specs' => [], 'sku' => array_merge(ProduckSkuResource::make($sku)->resolve(), [ 'status' => ProductSku::STATUS_INVALID, ]), ]); } // 主商品的规格 $spuSpecs = []; if (count($original = (array) $sku->specs) > 0) { $skus = $spu->skus()->online()->get(['id', 'specs', 'stock', 'release_at']); $mapSkus = $skus->mapWithKeys(function ($item) { $key = implode('_', $item->specs) ?: $item->id; return [$key => $item]; }); foreach ($spu->specs as $spec) { $spuSpecItems = []; foreach ($spec->items as $value) { // 根据当前 SKU 的规格,组装可能出现的其它规格组合 $jSpecs = $original; $jSpecs[$spec->id] = $value; $key = implode('_', $jSpecs); $mapSku = $mapSkus->get($key); $spuSpecItems[] = [ 'name' => $value, 'selected' => $sku->is($mapSku), 'sku_id' => (int) $mapSku?->id, 'sku_stock' => (int) $mapSku?->saleable_stock, ]; } $spuSpecs[] = [ 'name' => $spec->name, 'items' => $spuSpecItems, ]; } } return response()->json([ 'spu_specs' => $spuSpecs, 'sku' => array_merge(ProduckSkuResource::make($sku)->resolve(), [ 'status' => ProductSku::STATUS_ONLINE, ]), ]); } /** * 过滤商品 * * @param \Illuminate\Http\Request $request * @return \Illuminate\Pagination\Paginator */ protected function filterProducts(Request $request): Paginator { $input = $request->input(); if ($request->isNotFilled('sort')) { $input['sort'] = '-id'; } return ProductSku::select(['id', 'name', 'cover', 'sell_price', 'vip_price', 'sales']) ->filter($input) ->online() ->whereRelation('category', 'is_show', true) ->simplePaginate(PaginatorHelper::resolvePerPage('per_page', 20, 50)); } /** * 按分区过滤商品 * * @param \Illuminate\Http\Request $request * @return \Illuminate\Pagination\Paginator */ protected function filterProductsByPart(Request $request): Paginator { $productPart = ProductPart::where('key', $request->input('part'))->first(); if ($productPart === null) { return new Paginator([], $this->getPerPage($request), Paginator::resolveCurrentPage()); } $paginator = ProductPartSku::with('sku:id,name,cover,sell_price,vip_price,sales') ->whereHas('sku', function ($query) { $query->online()->whereRelation('category', 'is_show', true); }) ->where('part_id', $productPart->id) ->latest('sort') ->simplePaginate(PaginatorHelper::resolvePerPage('per_page', 20, 50)); return $paginator->through(function ($item) { return $item->sku; }); } }