|
@@ -381,10 +381,8 @@ class PublicController extends AbstractController
|
|
|
}
|
|
|
$fileName = $requireData['fileName'] . time() . mt_rand(1, 1000000) . '.zip';
|
|
|
$zipFileName = $allDir . DIRECTORY_SEPARATOR . $requireData['fileName'] . time() . mt_rand(1, 1000000) . '.zip';
|
|
|
-// $zipFileName = 'public/zip/files.zip';
|
|
|
|
|
|
if ($zip->open($zipFileName, ZipArchive::CREATE) === true) {
|
|
|
- // 将要下载的文件逐个添加到zip文件中
|
|
|
/** @var array<string> $files */
|
|
|
$files = [];
|
|
|
if (is_array($requireData['files'])) {
|
|
@@ -393,47 +391,94 @@ class PublicController extends AbstractController
|
|
|
$files = [$requireData['files']];
|
|
|
}
|
|
|
|
|
|
+ // 使用协程并行处理文件
|
|
|
+ $fileService = \Hyperf\Support\make(\App\Service\FileService::class);
|
|
|
+ $promises = [];
|
|
|
+
|
|
|
foreach ($files as $key => $filePathu) {
|
|
|
if (!is_string($filePathu)) {
|
|
|
continue;
|
|
|
}
|
|
|
|
|
|
- // 生成文件名:key + 1
|
|
|
- $fileName = $requireData['names'][$key]; //($key + 1) . $this->getFileExtension($filePathu);
|
|
|
+ $fileName = $requireData['names'][$key];
|
|
|
|
|
|
// 处理远程URL文件
|
|
|
if (filter_var($filePathu, FILTER_VALIDATE_URL)) {
|
|
|
- $this->addRemoteFileToZip($zip, $filePathu, $fileName);
|
|
|
- } else {
|
|
|
- // 处理本地文件
|
|
|
- if (!file_exists($filePathu)) {
|
|
|
- // 尝试添加public前缀
|
|
|
- $fullPath = 'public/' . $filePathu;
|
|
|
- if (!file_exists($fullPath)) {
|
|
|
- // 尝试使用绝对路径
|
|
|
- $fullPath = BASE_PATH . '/public/' . $filePathu;
|
|
|
- if (!file_exists($fullPath)) {
|
|
|
- continue; // 跳过不存在的文件
|
|
|
- }
|
|
|
- }
|
|
|
- $filePathu = $fullPath;
|
|
|
+ // 检查缓存
|
|
|
+ $cachedContent = $fileService->getCachedFile($filePathu);
|
|
|
+ if ($cachedContent !== null) {
|
|
|
+ $zip->addFromString($fileName, $cachedContent);
|
|
|
+ continue;
|
|
|
}
|
|
|
|
|
|
- // 确保文件存在且可读
|
|
|
- if (is_file($filePathu) && is_readable($filePathu)) {
|
|
|
- $zip->addFile($filePathu, $fileName);
|
|
|
- }
|
|
|
+ // 添加到并行下载队列
|
|
|
+ $promises[] = function() use ($fileService, $zip, $filePathu, $fileName) {
|
|
|
+ $content = $fileService->downloadWithProgress($filePathu, function($ch, $downloadSize, $downloaded) {
|
|
|
+ // 可以在这里添加下载进度记录
|
|
|
+ if ($downloadSize > 0) {
|
|
|
+ $progress = round($downloaded / $downloadSize * 100);
|
|
|
+ // 记录进度...
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if ($content !== false) {
|
|
|
+ // 缓存文件内容
|
|
|
+ $fileService->cacheFile($filePathu, $content);
|
|
|
+ // 添加到zip
|
|
|
+ $zip->addFromString($fileName, $content);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ } else {
|
|
|
+ // 本地文件处理
|
|
|
+ $this->addLocalFileToZip($zip, $filePathu, $fileName);
|
|
|
}
|
|
|
}
|
|
|
- // 关闭zip文件
|
|
|
+
|
|
|
+ // 并行执行所有下载任务
|
|
|
+ if (!empty($promises)) {
|
|
|
+ // 使用协程并发执行所有下载任务
|
|
|
+ \Hyperf\Coroutine\parallel($promises);
|
|
|
+ }
|
|
|
+
|
|
|
$zip->close();
|
|
|
- // 将zip文件提供给用户进行下载
|
|
|
$fileUrlName = explode("public", $zipFileName);
|
|
|
return Result::success(['fileUrl' => env('HOST') . $fileUrlName[1]]);
|
|
|
} else {
|
|
|
return Result::error('无法创建zip文件');
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 处理本地文件添加到zip
|
|
|
+ */
|
|
|
+ private function addLocalFileToZip($zip, $filePath, $fileName): void
|
|
|
+ {
|
|
|
+ if (!file_exists($filePath)) {
|
|
|
+ // 尝试不同的路径组合
|
|
|
+ $paths = [
|
|
|
+ 'public/' . $filePath,
|
|
|
+ BASE_PATH . '/public/' . $filePath
|
|
|
+ ];
|
|
|
+
|
|
|
+ foreach ($paths as $path) {
|
|
|
+ if (file_exists($path)) {
|
|
|
+ $filePath = $path;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (is_file($filePath) && is_readable($filePath)) {
|
|
|
+ // 对大文件使用流式处理
|
|
|
+ if (filesize($filePath) > 10 * 1024 * 1024) { // 10MB
|
|
|
+ $stream = fopen($filePath, 'r');
|
|
|
+ $zip->addFromStream($stream, $fileName);
|
|
|
+ fclose($stream);
|
|
|
+ } else {
|
|
|
+ $zip->addFile($filePath, $fileName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
/**
|
|
|
* 添加远程文件到zip
|