Procházet zdrojové kódy

Naming rule apply to files

moell před 5 měsíci
rodič
revize
67c58659cf

+ 8 - 1
app/Services/File/Upload/FilesUploadTrait.php

@@ -10,6 +10,7 @@ use App\Models\BimFile;
 use App\Models\ContainerContent;
 use App\Models\Enums\FileObjectType;
 use App\Models\File;
+use App\Services\NamingRule\NamingRuleCheck;
 use Illuminate\Http\Request;
 use Illuminate\Http\UploadedFile;
 use Illuminate\Support\Facades\Auth;
@@ -34,20 +35,26 @@ trait FilesUploadTrait
             $this->object = $this->fileObjectType->modelBuilderAllowed($request->object_id)->findOrFail($request->object_id);
         }
 
+        $nameRuleCheck = new NamingRuleCheck($this->fileObjectType, $this->object);
+
         $filesSize = 0;
 
         $files = $request->file("files");//文件流
         if ($files) {
-            foreach ($files as $file) {
+            $fileNames = $this->request->get("file_names", []);
+            foreach ($files as $index => $file) {
                 throw_validation_if(!$file->isValid(), "File upload failed.");
 
                 $filesSize += $file->getSize();
+
+                $nameRuleCheck->check($fileNames[$index] ?? $file->getClientOriginalName());
             }
         } else {//文件路径
             $files = $request->get('files', []);
 
             foreach ($files as $file) {
                 $filesSize += (int) ($file['size'] ?? 0);
+                $nameRuleCheck->check($file['title']);
             }
         }
 

+ 107 - 0
app/Services/NamingRule/NamingRuleCheck.php

@@ -0,0 +1,107 @@
+<?php
+
+namespace App\Services\NamingRule;
+
+use App\Models\Asset;
+use App\Models\CustomField;
+use App\Models\Enums\CustomFieldType;
+use App\Models\Enums\FileObjectType;
+use App\Models\Enums\LibraryType;
+use App\Models\Project;
+use Illuminate\Database\Eloquent\Collection;
+
+class NamingRuleCheck
+{
+    protected ?Collection $customFieldsKeyBy = null;
+
+    public function __construct(
+        protected FileObjectType $fileObjectType,
+        protected ?object $object = null
+    )
+    {
+        if ($this->object) {
+            $this->customFieldsKeyBy = CustomField::query()
+                ->where("group", $this->object->naming_rule_id)
+                ->get()
+                ->keyBy("key");
+        }
+    }
+
+    public function check(string $name)
+    {
+        if (! $this->object || ! $this->object->namingRule) {
+            return;
+        }
+
+        $fileName = pathinfo($name)['filename'];
+
+        $result = $this->parse($fileName, $this->getNamingRuleCode(), $this->object->namingRule->combination_rules);
+
+        throw_validation_if(! $result, sprintf("'%s' does not conform to the naming rules", $fileName));
+    }
+
+
+    protected function parse(string $name, string $code, array $rules): bool|array
+    {
+        if (!str_starts_with($name, $code)) {
+            return false;
+        }
+
+        $remainingString = substr($name, strlen($code));
+
+        $items = [];
+        foreach ($rules as $rule) {
+            $expectedLink = $rule['link'];  // 期望的连接符
+
+            if (!str_starts_with($remainingString, $expectedLink)) {
+                return false;
+            }
+
+            $remainingString = substr($remainingString, strlen($expectedLink));
+
+            $nextLinkPos = false;
+            foreach ($rules as $r) {
+                $pos = strpos($remainingString, $r['link']);
+                if ($pos !== false && $pos > 0) {
+                    $nextLinkPos = $pos;
+                    break;
+                }
+            }
+
+            if ($nextLinkPos !== false) {
+                $fieldValue = substr($remainingString, 0, $nextLinkPos);
+                $remainingString = substr($remainingString, $nextLinkPos);
+            } else {
+                $fieldValue = $remainingString;
+                $remainingString = '';
+            }
+
+            $customField = $this->customFieldsKeyBy[$rule['field']];
+            if ($customField->type == CustomFieldType::SELECT->value) {
+                if (! in_array($fieldValue, array_column($customField->options, "value"))) {
+                    return false;
+                }
+            }
+
+            $items[$customField->key] = $fieldValue;
+        }
+
+        return $items;
+    }
+
+
+    protected function getNamingRuleCode()
+    {
+        $library = $this->object->library;
+
+        $code = match (LibraryType::tryFrom($library->type)) {
+            LibraryType::PROJECT => Project::query()->find($library->project_id)?->code,
+            LibraryType::ASSET => Asset::query()->find($library->asset_id)?->code,
+            LibraryType::CUSTOM => "custom"
+        };
+
+        throw_validation_if(! $code, "The supported type or selected item does not exist");
+
+        return $code;
+    }
+}