import 'api_service.dart'; import '../core/utils/app_logger.dart'; import '../core/utils/file_utils.dart'; import 'custom_line_service.dart'; /// 文件服务 class FileService { /// 列出文件 Future> listFiles({ required String uri, int page = 0, int? pageSize, String? orderBy, String? orderDirection, String? nextPageToken, }) async { final params = { 'uri': FileUtils.toCloudreveUri(uri), 'page': page, 'page_size': pageSize, 'order_by': orderBy, 'order_direction': orderDirection, 'next_page_token': nextPageToken, }; final response = await ApiService.instance.get>( '/file', queryParameters: params, ); return response; } /// 按 Cloudreve V4 预设分类列出文件。 /// /// category 可用值:image / video / audio / document Future> listFilesByCategory({ required String category, int page = 0, int? pageSize, String? orderBy, String? orderDirection, String? nextPageToken, }) { final normalizedCategory = category.trim().toLowerCase(); final categoryUri = 'cloudreve://my?category=$normalizedCategory'; return listFiles( uri: categoryUri, page: page, pageSize: pageSize, orderBy: orderBy, orderDirection: orderDirection, nextPageToken: nextPageToken, ); } /// 创建文件/文件夹 Future> createFile({ required String uri, required String type, bool? errOnConflict, Map? metadata, }) async { final data = { 'uri': FileUtils.toCloudreveUri(uri), 'type': type, 'err_on_conflict': ?errOnConflict, 'metadata': ?metadata, }; final response = await ApiService.instance.post>( '/file/create', data: data, ); return response; } /// 删除文件 Future deleteFiles({ required List uris, bool unlink = false, bool skipSoftDelete = false, }) async { final data = { 'uris': uris.map((uri) => FileUtils.toCloudreveUri(uri)).toList(), if (unlink) 'unlink': true, if (skipSoftDelete) 'skip_soft_delete': true, }; await ApiService.instance.delete('/file', data: data); } /// 移动/复制文件 Future moveFiles({ required List uris, required String dst, bool copy = false, }) async { final data = { 'uris': uris.map((uri) => FileUtils.toCloudreveUri(uri)).toList(), 'dst': FileUtils.toCloudreveUri(dst), 'copy': copy, }; await ApiService.instance.post('/file/move', data: data); } /// 重命名文件(返回更新后的文件对象) Future> renameFile({ required String uri, required String newName, }) async { final data = { 'uri': FileUtils.toCloudreveUri(uri), 'new_name': newName, }; final response = await ApiService.instance.post>( '/file/rename', data: data, ); return response; } /// 获取下载链接 Future> getDownloadUrls({ required List uris, bool download = true, bool? redirect, String? entity, bool? usePrimarySiteUrl, bool? skipError, bool? archive, bool? noCache, String? contextHint, }) async { final data = { 'uris': uris.map((uri) => FileUtils.toCloudreveUri(uri)).toList(), 'download': download, 'redirect': ?redirect, 'entity': ?entity, 'use_primary_site_url': ?usePrimarySiteUrl, 'skip_error': ?skipError, 'archive': ?archive, 'no_cache': ?noCache, }; final headers = {}; if (contextHint != null) { headers['X-Cr-Context-Hint'] = contextHint; } final response = await ApiService.instance.post>( '/file/url', data: data, headers: headers, ); await _activateCustomLineForUrls(response); return response; } Future _activateCustomLineForUrls(Map response) async { final urls = response['urls']; if (urls is! List) return; final resolvedUrls = []; for (final item in urls) { if (item is! Map) continue; final url = item['url']?.toString(); if (url == null || url.isEmpty) continue; resolvedUrls.add(url); } await CustomLineService.instance.activateSelectedNodeForUrls(resolvedUrls); } /// 创建直接链接(分享链接) Future>> createDirectLinks({ required List uris, }) async { final data = { 'uris': uris.map((uri) => FileUtils.toCloudreveUri(uri)).toList(), }; final response = await ApiService.instance.put>>( '/file/source', data: data, ); return response; } /// 恢复文件(从回收站) Future restoreFiles({required List uris}) async { final data = { 'uris': uris.map((uri) => FileUtils.toCloudreveUri(uri)).toList(), }; await ApiService.instance.post('/file/restore', data: data); } /// 列出回收站文件 Future> listTrashFiles({ int page = 0, int? pageSize, }) async { final params = { 'uri': 'cloudreve://trash', 'page': page, 'page_size': pageSize, }; final response = await ApiService.instance.get>( '/file', queryParameters: params, ); return response; } /// 搜索文件 Future> searchFiles({ String uri = '/', required String name, bool caseFolding = false, int page = 0, int? pageSize, }) async { // 构造搜索 URI: cloudreve://my?name=xxx final cloudreveUri = '${FileUtils.toCloudreveUri(uri)}?name=$name'; final params = { 'uri': cloudreveUri, 'page': page, 'case_folding': caseFolding, 'page_size': pageSize, }; final response = await ApiService.instance.get>( '/file', queryParameters: params, ); AppLogger.d('Search files ---------> : $response'); return response; } /// 获取文件/文件夹详细信息 Future> getFileInfo({ String? uri, String? id, bool extended = false, bool folderSummary = false, }) async { final params = { if (uri != null) 'uri': FileUtils.toCloudreveUri(uri), 'id': ?id, 'extended': extended, 'folder_summary': folderSummary, }; final response = await ApiService.instance.get>( '/file/info', queryParameters: params, ); AppLogger.d("getFileInfo --> $response"); return response; } /// 设为当前版本 Future setFileVersion({ required String uri, required String version, }) async { final data = { 'uri': FileUtils.toCloudreveUri(uri), 'version': version, }; await ApiService.instance.post('/file/version/current', data: data); } /// 删除版本 Future deleteFileVersion({ required String uri, required String version, }) async { final data = { 'uri': FileUtils.toCloudreveUri(uri), 'version': version, }; await ApiService.instance.delete('/file/version', data: data); } }