DownloadService.php 5.0 KB

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