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)); } /** * 商品列表:价格取当前门店客户等级价(未绑等级的门店报错); * ?category_id=&keyword=&page=&pageSize= */ #[GetRoute('/product/list', authorize: true)] public function products(Request $request): JsonResponse { $user = $this->currentUser($request); $store = $this->ensureStoreBound($user); if ($store->level_id <= 0) { throw new RepositoryException('门店未设置客户等级,无法展示价格,请联系客服'); } $query = ProductModel::query() ->where('status', ProductModel::STATUS_ON) ->with('category:id,name') ->with(['prices' => static fn ($q) => $q->where('level_id', $store->level_id)]); $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 . '%') ->orWhere('spec', 'like', '%' . $keyword . '%'); }); } $pageSize = (int) $request->input('pageSize', 10); $data = $query->orderBy('sort') ->orderBy('id') ->paginate($pageSize) ->toArray(); // 扁平化价格:prices[0].price → price(未设等级价为 null) foreach ($data['data'] as &$row) { $row['price'] = $row['prices'][0]['price'] ?? null; unset($row['prices']); } return $this->success($data); } }