model = FileFolderModel::class; $this->selectField = ['id', 'pid', 'name', 'sort', 'status', 'created_at', 'updated_at']; $this->queryField = ['name' => 'like', 'pid' => '=', 'status' => '=']; $this->orderBy = ['name' => 'sort', 'sort' => 'asc']; } /** * 列表,带每个文件夹下的素材数 * * @throws ContainerExceptionInterface * @throws NotFoundExceptionInterface */ public function list(): array { $result = $this->getPageList(); $ids = array_column($result['items'], 'id'); $counts = empty($ids) ? [] : FileModel::whereIn('folder_id', $ids) ->where('deleted_at', 0) ->selectRaw('folder_id, COUNT(*) as total') ->groupBy('folder_id') ->pluck('total', 'folder_id') ->all(); foreach ($result['items'] as &$item) { $item['file_count'] = (int) ($counts[$item['id']] ?? 0); } unset($item); return $result; } /** * 目录树,素材库左侧栏直接用它渲染 */ public function option(): array { $rows = FileFolderModel::where('deleted_at', 0) ->orderBy('sort') ->orderBy('id') ->get(['id', 'pid', 'name', 'sort']) ->toArray(); return $this->utils->tree($rows); } /** * @throws Exception */ public function detail($id): mixed { return $this->getDetail($id); } /** * @throws Exception */ public function create($params): mixed { $params['pid'] = $this->assertParent((int) ($params['pid'] ?? 0)); return $this->insert($params); } /** * @throws Exception */ public function update($id, $params): mixed { if (array_key_exists('pid', $params)) { $pid = (int) $params['pid']; if ($pid === (int) $id) { $this->utils->errorThrow('上级文件夹不能是自己'); } $params['pid'] = $this->assertParent($pid); } return $this->save($id, $params); } /** * 删除文件夹:有子目录或仍有素材时拒绝 * * 直接删会让里面的素材挂在一个查不到的 folder_id 上, * 按文件夹筛选时那批文件就再也点不出来 —— 文件还在,人找不到。 * * @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 (FileFolderModel::whereIn('pid', $ids)->where('deleted_at', 0)->exists()) { $this->utils->errorThrow('存在子文件夹,请先删除子文件夹'); } if (FileModel::whereIn('folder_id', $ids)->where('deleted_at', 0)->exists()) { $this->utils->errorThrow('该文件夹下仍有素材,请先移动素材'); } return $this->del($ids); } /** * @throws Exception */ private function assertParent(int $pid): int { if ($pid <= 0) { return 0; } if (!FileFolderModel::where('id', $pid)->where('deleted_at', 0)->exists()) { $this->utils->notFound('上级文件夹不存在'); } return $pid; } }