Преглед изворни кода

feat:新增模型上传接口

waymen пре 5 месеци
родитељ
комит
7b4f20bbd1

+ 18 - 0
app/Http/Controllers/API/FileController.php

@@ -141,6 +141,24 @@ class FileController extends Controller
 
     }
 
+    /**
+     * 模型上传
+     * @param \App\Http\Requests\API\File\FileUploadRequest $request
+     * @return
+     */
+    public function modelUpload(FileUploadRequest $request)
+    {
+        set_time_limit(0);
+
+        $uploadedFiles = (new FilesUploadService($request))->uploadModels();
+
+        if ($request->object_id !== null) {
+            ActionRepository::createByFile($request->object_id, $request->object_type, ObjectAction::UPLOADED);
+        }
+
+        return $this->successData($uploadedFiles);
+    }
+
     public function companyUpload(FileUploadRequest $request)
     {
         set_time_limit(0);

+ 1 - 1
app/Http/Controllers/JsonResponseHelper.php

@@ -113,7 +113,7 @@ trait JsonResponseHelper
         return response()->json($data, Response::HTTP_OK, $headers, $options);
     }
 
-    protected function successData($data): JsonResponse
+    protected function successData($data = null): JsonResponse
     {
         return $this->success(['data' => $data]);
     }

+ 42 - 15
app/Http/Requests/API/File/FileUploadRequest.php

@@ -3,8 +3,8 @@
 namespace App\Http\Requests\API\File;
 
 use App\Models\Enums\FileObjectType;
-use App\Models\User;
 use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Arr;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Validation\Rules\Enum;
 use Illuminate\Validation\Rules\File;
@@ -26,18 +26,36 @@ class FileUploadRequest extends FormRequest
      */
     public function rules(): array
     {
+        $routeName = $this->route()->getName();
+
+        switch ($routeName) {
+            case 'file.cos.token':
+                return $this->cosTokenRules();
+            case 'file.modelUpload':
+                return $this->modelUploadRules();
+        }
+
+        $baseRules = $this->baseRules();
+
         $rules = [
-            "object_type" => ['required', new Enum(FileObjectType::class)],
+            "files.*" => 'required',
+            "name" => '',
+            "source" => "in:1,2",
         ];
 
-        if ($this->route()->getName() == 'file.cos.token') {
-            return $rules;
-        }
+        $rules = array_merge($baseRules, $rules);
 
-        $appendRules = [
-            "files.*" => [
-                'required',
-            ],
+        $rules['file.*'][] = $this->get("source", 1) == 1
+            ? File::types(['jpeg', 'png', 'gif'])->max("10mb")
+            : File::types(['txt', 'jpeg', 'png', 'gif', 'pdf', 'xls', 'xlsx', 'zip', 'wps', 'docx', 'doc', 'pptx', 'mp4', 'avi', 'mpeg', 'mov'])->max("2gb");
+
+        return $rules;
+    }
+
+    private function baseRules()
+    {
+        return [
+            "object_type" => ['required', new Enum(FileObjectType::class)],
             "object_id" => [
                 function ($attribute, $value, $fail) {
                     $exist = FileObjectType::from($this->get("object_type"))
@@ -50,15 +68,24 @@ class FileUploadRequest extends FormRequest
                     }
                 }
             ],
-            "source" => "in:1,2",
         ];
+    }
 
-        $rules = array_merge($rules, $appendRules);
+    protected function cosTokenRules(): array
+    {
+        return Arr::only($this->baseRules(), ['object_type']);
+    }
 
-        $rules['file.*'][] = $this->get("source", 1) == 1
-            ? File::types(['jpeg', 'png', 'gif'])->max("10mb")
-            : File::types(['txt', 'jpeg', 'png', 'gif', 'pdf', 'xls', 'xlsx', 'zip', 'wps', 'docx', 'doc', 'pptx', 'mp4', 'avi', 'mpeg', 'mov'])->max("2gb");
+    protected function modelUploadRules(): array
+    {
+        $baseRules = $this->baseRules();
+        $rules =  [
+            'files' => 'required',
+            'files.*.size' => 'required|integer',
+            'files.*.title' => 'required|string',
+            'files.*.pathname' => 'required|string',
+        ];
 
-        return $rules;
+        return array_merge($baseRules, $rules);
     }
 }

+ 1 - 1
app/Libraries/BIM/Contacts/BIMContact.php

@@ -8,7 +8,7 @@ use Illuminate\Http\UploadedFile;
 
 interface BIMContact {
 
-    public function uploadFile(UploadedFile $file, BimFileBO $bimFileBO);
+    public function uploadFile(UploadedFile|null $file, BimFileBO $bimFileBO);
 
     public function downloadSourceFile();
 

+ 1 - 1
app/Libraries/BIM/Glendale/Glendale.php

@@ -141,7 +141,7 @@ class Glendale extends BIMAbstract
         ]);
     }
 
-    public function uploadFile(UploadedFile $file, BimFileBO $bimFileBO): array
+    public function uploadFile(UploadedFile|null $file, BimFileBO $bimFileBO): array
     {
         if (!empty($bimFileBO->modelDownloadUrl)) { //指定URL方式上传
             $result = $this->uploadModelByUrl($bimFileBO);

+ 19 - 0
app/Services/File/Upload/FilesUploadService.php

@@ -41,4 +41,23 @@ class FilesUploadService
 
         return $uploadedFiles;
     }
+
+    /**
+     * 上传BIM模型
+     * @return array
+     */
+    public function uploadModels(): array
+    {
+        $files = $this->request->get("files", []);
+        $items = [];
+
+        foreach ($files as $file) {
+            $item = $this->uploadFileWithPath($this->request, $file['pathname'], $file['title'], $file['size']);
+
+            $items[] = $item;
+        }
+
+        $uploadedFiles = $this->storeFiles($items);
+        return $uploadedFiles;
+    }
 }

+ 53 - 9
app/Services/File/Upload/FilesUploadTrait.php

@@ -35,12 +35,23 @@ trait FilesUploadTrait
         }
 
         $filesSize = 0;
-        foreach ($request->file("files") as $file) {
-            throw_validation_if(!$file->isValid(), "File upload failed.");
 
-            $filesSize += $file->getSize();
+        $files = $request->file("files");//文件流
+        if ($files) {
+            foreach ($files as $file) {
+                throw_validation_if(!$file->isValid(), "File upload failed.");
+
+                $filesSize += $file->getSize();
+            }
+        } else {//文件路径
+            $files = $request->get('files', []);
+
+            foreach ($files as $file) {
+                $filesSize += (int) ($file['size'] ?? 0);
+            }
         }
 
+
         throw_validation_if(
             $filesSize + Auth::user()->company->used_storage_capacity > Auth::user()->company->storage_size,
             "Storage capacity is insufficient, please contact the administrator."
@@ -49,6 +60,44 @@ trait FilesUploadTrait
         return $filesSize;
     }
 
+    protected function returnUploadResult(string $extension, string $fileName, string $path = '', int $size = 0, Request $request)
+    {
+        $modelType = $request->input('model_type', '');
+
+        if ($this->isBIM($extension) || $modelType == 'osgb' && $request->object_type == FileObjectType::CONTAINER->value) {
+            $bimFileBO = new BimFileBO($extension, $fileName, $modelType);
+            if (!empty($path)) {
+                $bimFileBO->modelDownloadUrl = Storage::url($path);
+            }
+            $bimFileBO->setPointCloudConfigJson($request->input('pointCloudConfigJson', []));
+
+            $data['bim'] = BIMFactory::make()->uploadFile($file ?? null, $bimFileBO);
+        }
+
+        $data['file'] = [
+            'pathname' => $path,
+            'title' => $fileName,
+            'size' => $size,
+            'extension' => $extension,
+            'object_type' => $request->object_type,
+            'object_id' => $request->object_id,
+            'created_by' => Auth::id(),
+            'company_id' => Auth::user()->company_id,
+            'source' => $request->get("source", 1),
+            'uuid' => $request->get("uuid"),
+            'is_bim' => count($data['bim']) > 0 ? 1 : 0,
+        ];
+
+        return $data;
+    }
+
+    protected function uploadFileWithPath(Request $request, string $path, string $fileName, int $size = 0)
+    {
+        $extension = pathinfo($path, PATHINFO_EXTENSION);
+
+        return $this->returnUploadResult($extension, $fileName, $path, $size, $request);
+    }
+
     protected function uploadFile(Request $request, UploadedFile $file, ?ProgressBar $progressBar = null): array
     {
         $extension = $file->getClientOriginalExtension()
@@ -61,23 +110,18 @@ trait FilesUploadTrait
             sprintf("%s.%s", md5(uniqid()), $extension),
             $progressBar
         );
-        $modelDownloadUrl = Storage::url($pathname);
 
         $data = [
             'bim' => [],
         ];
 
-        $isBimFile = 0;
         $modelType = $request->input('model_type', '');
 
         if ($this->isBIM($extension) || $modelType == 'osgb' && $request->object_type == FileObjectType::CONTAINER->value) {
             $bimFileBO = new BimFileBO($extension, $file->getClientOriginalName(), $modelType);
-            // $bimFileBO->modelDownloadUrl = $modelDownloadUrl;
             $bimFileBO->setPointCloudConfigJson($request->input('pointCloudConfigJson', []));
 
             $data['bim'] = BIMFactory::make()->uploadFile($file, $bimFileBO);
-
-            $isBimFile = true;
         }
 
         $data['file'] = [
@@ -91,7 +135,7 @@ trait FilesUploadTrait
             'company_id' => Auth::user()->company_id,
             'source' => $request->get("source", 1),
             'uuid' => $request->get("uuid"),
-            'is_bim' => $isBimFile,
+            'is_bim' => count($data['bim']) > 0 ? 1 : 0,
         ];
 
         return $data;

+ 2 - 0
routes/api.php

@@ -22,6 +22,7 @@ Route::post("/reset-password", [API\AuthController::class, "resetPassword"]);
 Route::post("register/company", [API\CompanyController::class, "registerCompany"]);
 Route::post("company-file-upload", [API\FileController::class, "companyUpload"]);
 //暂时为免登录
+Route::post("model-upload", [API\FileController::class, "modelUpload"])->name("file.modelUpload");
 Route::get("file/download/{uuid}/share-file", [API\FileController::class, "downloadShareFile"])
     ->name("file.download-share-file");
 Route::post("glendale/callback", [API\GlendaleController::class, "callback"])->name('glendale.callback');
@@ -248,6 +249,7 @@ Route::middleware(['auth:sanctum','account.limit'])->group(function () {
         Route::patch("action/{action}/comment", [API\ActionController::class, "updateComment"])->name("action.update-comment");
 
         Route::post("file-upload", [API\FileController::class, "upload"])->name("file.upload");
+        
 //        Route::get("file/{object_type}/{object_id}", [API\FileController::class, "byObject"])->name("file.by-object");
         Route::post("file/{file}/download", [API\FileController::class, "download"])->name("file.download");
         Route::post("file/download-zip", [API\FileController::class, "downloadZip"])->name("file.download-zip");