model = CategoryModel::class; $this->selectField = ['id', 'name', 'url', 'pid', 'sort', 'status', 'created_at', 'updated_at']; $this->queryField = ['name' => 'like', 'pid' => '=', 'status' => '=']; // 有 sort 列后按排序值,同值再按 id,保证稳定 $this->orderBy = ['name' => 'sort', 'sort' => 'asc']; $this->media = MediaUrlService::getInstance(); } /** * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ public function list(): array { $result = $this->getPageList(); $this->media->publicEach($result['items'], ['url']); return $result; } /** * 分类树。老接口在首位塞了一个 {id:0,name:'全部'} 供小程序做「全部」标签用, * 这里保留该行为,但只在显式要求时加,后台表单选上级时不需要它。 */ public function option(): array { $withAll = filter_var(request()->get('with_all', false), FILTER_VALIDATE_BOOLEAN); $rows = CategoryModel::where('deleted_at', 0) ->orderBy('sort', 'asc') ->orderBy('id', 'asc') ->get(['id', 'name', 'url', 'pid', 'sort']) ->toArray(); $this->media->publicEach($rows, ['url']); $tree = $this->utils->tree($rows); if ($withAll) { array_unshift($tree, ['id' => 0, 'name' => '全部', 'url' => '', 'pid' => 0]); } return $tree; } /** * @throws Exception */ public function detail($id): mixed { $info = $this->getDetail($id); $info->url = $this->media->toPublic($info->url); return $info; } public function create($params): mixed { $params['url'] = $this->media->firstOf($params['url'] ?? ''); return $this->insert($params); } /** * @throws Exception */ public function update($id, $params): mixed { if (array_key_exists('url', $params)) { $params['url'] = $this->media->firstOf($params['url']); } if (array_key_exists('pid', $params)) { $pid = (int) $params['pid']; if ($pid === (int) $id) { $this->utils->errorThrow('上级分类不能是自己'); } } return $this->save($id, $params); } /** * 删除分类:有子分类或仍挂着商品时拒绝,避免商品失去归属后在小程序里查不到 * @throws Exception */ public function delete($id): mixed { $ids = array_values(array_filter(array_map('intval', is_array($id) ? $id : [$id]))); if (empty($ids)) { $this->utils->errorThrow('参数错误'); } if (CategoryModel::whereIn('pid', $ids)->where('deleted_at', 0)->exists()) { $this->utils->errorThrow('存在子分类,请先删除子分类'); } if (CatalogueModel::whereIn('category_id', $ids)->where('deleted_at', 0)->exists()) { $this->utils->errorThrow('该分类下仍有商品,请先调整商品分类'); } return $this->del($ids); } /** * @throws Exception */ public function status($id, $status): mixed { return $this->save($id, ['status' => (int) $status]); } }