where('status', ProductModel::STATUS_ON) ->distinct() ->pluck('category_id') ->map(static fn ($id) => (int) $id) ->filter(static fn (int $id) => $id > 0); $categories = ProductCategoryModel::query() ->where('status', ProductCategoryModel::STATUS_NORMAL) ->get() ->keyBy('id'); // 保留有上架商品的分类 + 其全部祖先 $keep = []; foreach ($activeCategoryIds as $categoryId) { $cursor = $categoryId; $guard = 0; while ($cursor > 0 && $guard++ < 20 && $categories->has($cursor)) { $keep[$cursor] = true; $cursor = (int) $categories[$cursor]->parent_id; } } $filtered = array_values(array_filter( $categories->toArray(), static fn (array $item) => isset($keep[$item['id']]) )); return $this->success(ProductCategoryModel::buildTree($filtered)); } /** * 商品列表 */ #[GetRoute('/product/list', authorize: false)] public function products(Request $request): JsonResponse { $query = ProductModel::query() ->where('status', ProductModel::STATUS_ON) ->with('category:id,name'); $categoryId = (int) $request->input('category_id', 0); if ($categoryId > 0) { $query->where('category_id', $categoryId); } $keyword = trim((string) $request->input('keyword', '')); if ($keyword !== '') { $query->where(static function ($q) use ($keyword) { $q->where('name', 'like', '%' . $keyword . '%'); }); } $pageSize = (int) $request->input('pageSize', 10); $data = $query->orderBy('sort') ->orderBy('id') ->paginate($pageSize) ->toArray(); foreach ($data['data'] as &$row) { $row['price'] = null; } // 用户 $user = $this->optionalUser($request); if (!$user) return $this->success($data); // 门店 $store = $this->boundStore($user); if(!$store) return $this->success('12313'); if ($store->level_id > 0) { foreach ($data['data'] as &$row) { $model = ProductPriceModel::where('product_id', $row['id'])->where('level_id', $store->level_id)->first(); $price = ProductPriceModel::calcActualPrice( $model->price_type, $model->price, $model->percent, $row->cost_price, ); $row['price'] = $price; } } return $this->success($data); } }