DownloadService.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. <?php
  2. namespace App\Services\File;
  3. use App\Http\Resources\API\FileDownloadResource;
  4. use App\Models\Enums\FileObjectType;
  5. use App\Models\Enums\FolderObjectType;
  6. use App\Models\Enums\ShareFileObjectType;
  7. use App\Models\File;
  8. use App\Models\Folder;
  9. use App\Models\ShareFile;
  10. use Carbon\Carbon;
  11. use Illuminate\Support\Collection;
  12. class DownloadService
  13. {
  14. public function downloadByIds(array $ids)
  15. {
  16. $files = File::query()->with(['folder'])->whereIn("id", $ids)->get();
  17. return $this->filesFormat($files);
  18. }
  19. /**
  20. * 下载分享文件
  21. *
  22. * @param string $uuid
  23. * @return array
  24. */
  25. public function downloadShareFile(string $uuid)
  26. {
  27. $shareFile = ShareFile::query()->where("uuid", $uuid)->firstOrFail();
  28. $objectType = ShareFileObjectType::from($shareFile->object_type);
  29. $objectType->modelBuilderAllowed($shareFile->object_id)->findOrFail($shareFile->object_id);
  30. $now = Carbon::now();
  31. $expirationTime = Carbon::parse($shareFile->expiration_time);
  32. if($now->gt($expirationTime)){
  33. return [];
  34. }
  35. $files = File::query()->with(['folder'])->whereIn("id", $shareFile->files)->get();
  36. return $this->filesFormat($files);
  37. }
  38. public function downloadAllLatest(string $objectType, string $objectId)
  39. {
  40. $folderObjectType = FolderObjectType::from($objectType);
  41. $object = $folderObjectType->modelBuilderAllowed()->findOrFail($objectId);
  42. $isExternalVersionControl = $this->isExternalVersionControl($folderObjectType);
  43. $fileIds = $isExternalVersionControl ? $this->versionFileIds($folderObjectType, $object) : [];
  44. $files = File::query()->with(['folder'])->where([
  45. 'object_type' => $objectType,
  46. 'object_id' => $objectId,
  47. ])->when(! $isExternalVersionControl, fn($query) => $query->where("is_latest_version", 1))
  48. ->when($fileIds, fn($query) => $query->whereIn("id", $fileIds))
  49. ->orderByDesc("version")
  50. ->get();
  51. $files = $isExternalVersionControl ? $this->getLatestFiles($files, $object) : $files;
  52. return $this->filesFormat($files);
  53. }
  54. protected function isExternalVersionControl(FolderObjectType $folderObjectType)
  55. {
  56. return $folderObjectType == FolderObjectType::CONTAINER && request("object_version", 0) > 0;
  57. }
  58. protected function getLatestFiles(Collection $files, $object)
  59. {
  60. $objectVersion = request('object_version') ?: $object->version;
  61. $items = [];
  62. foreach ($files->groupBy("folder_id") as $folderFiles) {
  63. foreach ($folderFiles as $file) {
  64. $isHide = $file->hide_object_version == 0
  65. ? (bool)$file->is_hide
  66. : $file->is_hide && $file->hide_object_version <= $objectVersion;
  67. if (! $isHide) {
  68. $items[] = $file;
  69. break;
  70. }
  71. }
  72. }
  73. return collect($items);
  74. }
  75. protected function versionFileIds(FolderObjectType $folderObjectType, $object)
  76. {
  77. $fileIds = [];
  78. if ($folderObjectType == FolderObjectType::CONTAINER) {
  79. $containerContent = $object->content(request('object_version') ?: $object->version)->first();
  80. throw_validation_if(! $containerContent, "The current version does not exist");
  81. $fileIds = explode(",", $containerContent->files);
  82. }
  83. return array_unique(array_filter($fileIds));
  84. }
  85. protected function filesFormat(Collection $files)
  86. {
  87. $folderIds = [];
  88. foreach ($files as $file) {
  89. $folderIds = [...$folderIds, ...explode(",", $file->folder?->path)];
  90. }
  91. $folders = Folder::query()->whereIn("id", array_unique(array_filter($folderIds)))->pluck("name", "id");
  92. $items = [];
  93. foreach ($files as $file) {
  94. $object = FileObjectType::from($file->object_type)
  95. ->modelBuilderAllowed($file->object_id)
  96. ->find($file->object_id);
  97. throw_validation_if(! $object, sprintf("File ID: %s, no permission to access", $file->id));
  98. $fileDownloadResource = (new FileDownloadResource($file))->toArray(request());
  99. $folderPath = [];
  100. foreach(array_filter(explode(",", $file->folder?->path)) as $folderId) {
  101. $folderPath[] = $folders->get($folderId);
  102. }
  103. $fileDownloadResource['folder_path'] = "/" . implode('/', $folderPath);
  104. $items[] = $fileDownloadResource;
  105. }
  106. return $items;
  107. }
  108. }