Browse Source

Merge branch 'glendale-bim' into dev

moell 10 months ago
parent
commit
5fddd992df

+ 2 - 0
app/Console/Commands/AddBimToConvertQueue.php

@@ -4,6 +4,7 @@ namespace App\Console\Commands;
 
 use App\Models\BimFile;
 use App\Models\Enums\BimFileConvertStatus;
+use App\Services\File\BIM\BIMDriverEnum;
 use App\Services\File\BIM\BIMFactory;
 use Carbon\Carbon;
 use Illuminate\Console\Command;
@@ -33,6 +34,7 @@ class AddBimToConvertQueue extends Command
         BimFile::query()
             ->where("created_at", ">=", Carbon::now()->subDay())
             ->whereIn("convert_status", [BimFileConvertStatus::NotAdded->value, BimFileConvertStatus::FAILED_TO_ADD_QUEUE->value])
+            ->where("bim_driver", BIMDriverEnum::BLACK_HOLE->value)
             ->chunkById(2000, function (Collection $bimFiles) {
                 $this->pushToQueue($bimFiles);
             });

+ 2 - 2
app/Console/Commands/SyncBimConvertStatus.php

@@ -42,9 +42,9 @@ class SyncBimConvertStatus extends Command
     {
         foreach ($bimFiles as $bimFile) {
             try {
-                $status = BIMFactory::make($bimFile->bim_driver)->findConvertStatus($bimFile->bim_data_set_id);
+                $statusArr = BIMFactory::make($bimFile->bim_driver)->findConvertStatus($bimFile->bim_data_set_id);
 
-                $bimFile->convert_status = $status;
+                $bimFile->fill($statusArr);
                 $bimFile->save();
             } catch (\Exception $exception) {
             }

+ 1 - 1
app/Models/BimFile.php

@@ -10,6 +10,6 @@ class BimFile extends Model
     use HasFactory;
 
     protected $fillable = [
-        'file_id', 'bim_driver', 'bim_data_set_id', 'bim_file_id', 'convert_status', 'error'
+        'file_id', 'bim_driver', 'bim_data_set_id', 'bim_file_id', 'convert_status', 'error', 'source_status',
     ];
 }

+ 16 - 0
app/Services/File/BIM/Abstracts/BIMAbstract.php

@@ -0,0 +1,16 @@
+<?php
+
+namespace App\Services\File\BIM\Abstracts;
+
+use App\Services\File\BIM\Contacts\BIMContact;
+
+abstract class BIMAbstract implements BIMContact
+{
+    protected function convertStatusFormat(int $status, $sourceStatus): array
+    {
+        return [
+            'convert_status' => $status,
+            'source_status' => $sourceStatus
+        ];
+    }
+}

+ 2 - 0
app/Services/File/BIM/BIMDriverEnum.php

@@ -5,4 +5,6 @@ namespace App\Services\File\BIM;
 enum BIMDriverEnum: string
 {
     case BLACK_HOLE = "black_hole";
+
+    case GLENDALE = "glendale";
 }

+ 3 - 1
app/Services/File/BIM/BIMFactory.php

@@ -4,6 +4,7 @@ namespace App\Services\File\BIM;
 
 use App\Services\File\BIM\BlackHole\BlackHole;
 use App\Services\File\BIM\Contacts\BIMContact;
+use App\Services\File\BIM\Glendale\Glendale;
 
 class BIMFactory
 {
@@ -12,7 +13,8 @@ class BIMFactory
         $driver = $driver ? $driver : config("bim.default");
 
         return match ($driver) {
-            "black_hole" => new BlackHole(),
+            BIMDriverEnum::BLACK_HOLE->value => new BlackHole(),
+            BIMDriverEnum::GLENDALE->value => new Glendale(),
         };
     }
 }

+ 6 - 3
app/Services/File/BIM/BlackHole/BlackHole.php

@@ -3,12 +3,13 @@
 namespace App\Services\File\BIM\BlackHole;
 
 use App\Models\Enums\BimFileConvertStatus;
+use App\Services\File\BIM\Abstracts\BIMAbstract;
 use App\Services\File\BIM\BIMDriverEnum;
 use App\Services\File\BIM\Contacts\BIMContact;
 use GuzzleHttp\Psr7;
 use Illuminate\Http\UploadedFile;
 
-class BlackHole implements BIMContact
+class BlackHole extends BIMAbstract
 {
     public function uploadFile(UploadedFile $file, array $params = [])
     {
@@ -68,7 +69,7 @@ class BlackHole implements BIMContact
         return $result['data'] ?? [];
     }
 
-    public function findConvertStatus(string $dataSetId)
+    public function findConvertStatus(string $dataSetId): array
     {
         $result = Client::getInstance()->post("/blackHole3D/project/dataSet/getConvertStatus", [
             'json' => [
@@ -76,13 +77,15 @@ class BlackHole implements BIMContact
             ]
         ]);
 
-        return match ($result['data']['status']) {
+        $status = match ($result['data']['status']) {
             0, 1 => BimFileConvertStatus::IN_QUEUE->value,
             2 => BimFileConvertStatus::CONVERTING->value,
             5 => BimFileConvertStatus::PAUSE->value,
             10 => BimFileConvertStatus::DONE->value,
             20 => BimFileConvertStatus::FAILED_TO_ADD_QUEUE->value,
         };
+
+        return $this->convertStatusFormat($status, $result['data']['status']);
     }
 
     public function addToConvertQueue(string $dataSetId): array

+ 1 - 1
app/Services/File/BIM/Contacts/BIMContact.php

@@ -10,7 +10,7 @@ interface BIMContact {
 
     public function downloadSourceFile();
 
-    public function findConvertStatus(string $dataSetId);
+    public function findConvertStatus(string $dataSetId): array;
 
     public function viewDataSetModel(array $dataSetIDS);
 

+ 77 - 0
app/Services/File/BIM/Glendale/Client.php

@@ -0,0 +1,77 @@
+<?php
+
+namespace App\Services\File\BIM\Glendale;
+
+
+use App\Services\File\BIM\Exceptions\FailedException;
+use Psr\Http\Message\ResponseInterface;
+
+
+class Client {
+
+    protected static ?Client $instance = null;
+
+    protected \GuzzleHttp\Client $client;
+
+    protected function __construct()
+    {
+        $this->client = new \GuzzleHttp\Client([
+            'base_uri' => config("bim.glendale.host"),
+            'http_errors' => false,
+            'debug' => false,
+            'headers' => [
+                'Accept' => "application/json",
+                'Token' => config("bim.glendale.token"),
+            ]
+        ]);
+    }
+
+    public static function getInstance(): Client
+    {
+        if (! self::$instance) {
+            self::$instance = new self();
+        }
+
+        return self::$instance;
+    }
+
+    public function request(string $method, string $uri, array $options = []): ?array
+    {
+        return $this->parseResponse($this->client->request($method, $uri, $options));
+    }
+
+    public function post(string $uri, array $options = []) {
+        return $this->request("POST", $uri, $options);
+    }
+
+    public function get(string $uri, array $params = []) {
+        return $this->request("GET", $uri, [
+            'query' => $params
+        ]);
+    }
+
+    protected function parseResponse(ResponseInterface $response): ?array
+    {
+        $body = json_decode((string)$response->getBody(), true);
+
+        return match ($response->getStatusCode()) {
+            200, 201, 204 => $this->parseStatusSuccessResponse($body),
+            default => throw new FailedException($body['message'] ?? $response->getReasonPhrase()),
+        };
+    }
+
+    protected function parseStatusSuccessResponse(array $body)
+    {
+        $isJson = json_last_error() == JSON_ERROR_NONE;
+
+        if (! $isJson) {
+            return [];
+        }
+
+        if ($body['code'] != 1) {
+            throw new FailedException($body['codeMsg']);
+        }
+
+        return $body;
+    }
+}

+ 50 - 0
app/Services/File/BIM/Glendale/ExtensionModelConfig.php

@@ -0,0 +1,50 @@
+<?php
+
+namespace App\Services\File\BIM\Glendale;
+
+class ExtensionModelConfig
+{
+    public static function getConfigOption(string $extension): array
+    {
+        return match ($extension) {
+            "rvt" => [
+                "style" => 1,
+                "zGrid" => 0,
+                "drawing" => 0,
+                "accuracy" => 5,
+                "vertexNormal" => 1,
+                "locationType" => 3,
+                "type" => 4,
+                "draco" => 1,
+                "isInstance" => 1,
+                "faceNumLimit" => 300000,
+                "materialType" => 1
+            ],
+            'dwg', 'dwf', 'dws', 'dwt' => [
+                "style" => 0,
+                "zGrid" => 0,
+                "drawing" => 0,
+                "accuracy" => 5,
+                "vertexNormal" => 0,
+                "unitRatio" => 0.001,
+                "type" => 2,
+                "isInstance" => 0,
+                "draco" => 0,
+                "engineType" => 1,
+                "combineTexture" => 0
+            ],
+            default => [
+                "style" => 0,
+                "zGrid" => 0,
+                "drawing" => 0,
+                "accuracy" => 5,
+                "vertexNormal" => 1,
+                "type" => 4,
+                "draco" => 1,
+                "isInstance" => 1,
+                "faceNumLimit" => 300000,
+                "materialType" => 1
+            ]
+        };
+    }
+}

+ 93 - 0
app/Services/File/BIM/Glendale/Glendale.php

@@ -0,0 +1,93 @@
+<?php
+
+namespace App\Services\File\BIM\Glendale;
+
+use App\Models\Enums\BimFileConvertStatus;
+use App\Services\File\BIM\Abstracts\BIMAbstract;
+use App\Services\File\BIM\BIMDriverEnum;
+use App\Services\File\BIM\Contacts\BIMContact;
+use Illuminate\Http\UploadedFile;
+use Illuminate\Support\Facades\Auth;
+use Ramsey\Uuid\Uuid;
+
+class Glendale extends BIMAbstract
+{
+
+    public function uploadFile(UploadedFile $file, array $params = [])
+    {
+        $uploadFormData = [
+            ['name' => 'file', 'contents' =>  fopen($file, 'r+'), 'filename' => $file->getClientOriginalName()]
+        ];
+
+        $result = Client::getInstance()->post('/api/app/model/upload-file', [
+            'query' => [
+                'input' => json_encode([
+                    'name' => $file->getClientOriginalName(),
+                    'initiatingUser' => Auth::user()->name,
+                    'uniqueCode' => Uuid::uuid4(),
+                    'priority' => 205,
+                    'isCAD' => $params['is_cad'],
+                    "configJson" => ExtensionModelConfig::getConfigOption($params['extension']),
+                ])
+            ],
+            'multipart' => $uploadFormData,
+        ]);
+
+        return [
+            'bim_data_set_id' => $result['datas']['lightweightName'],
+            'bim_file_id' => $result['datas']['lightweightName'],
+            'bim_convert_status' => BimFileConvertStatus::IN_QUEUE->value,
+            'bim_driver' => BIMDriverEnum::GLENDALE->value,
+        ];
+    }
+
+    public function downloadSourceFile()
+    {
+        // TODO: Implement downloadSourceFile() method.
+    }
+
+    public function findConvertStatus(string $dataSetId): array
+    {
+        $result = Client::getInstance()->post('/api/app/model/query-model-info', [
+            'query' => [
+                'LightweightName' => $dataSetId
+            ]
+        ]);
+
+        $getStatus = function($status) {
+            if ($status >= 1 && $status <= 99) {
+                return BimFileConvertStatus::CONVERTING->value;
+            }
+
+            if ($status <= 0) {
+                return BimFileConvertStatus::FAILED_TO_ADD_QUEUE->value;
+            }
+
+            return BimFileConvertStatus::IN_QUEUE->value;
+        };
+
+        $status = match ($result['datas'][0]['status']) {
+            0, 1, 101 => BimFileConvertStatus::IN_QUEUE->value,
+            100 => BimFileConvertStatus::DONE->value,
+            default => $getStatus($result['datas'][0]['status'])
+        };
+
+        return $this->convertStatusFormat($status, $result['datas'][0]['status']);
+    }
+
+    public function viewDataSetModel(array $dataSetIDS)
+    {
+        $result = Client::getInstance()->post('/api/app/model/query-model-info', [
+            'query' => [
+                'LightweightName' => $dataSetIDS[0]
+            ]
+        ]);
+
+        return $result['datas'] ?? [];
+    }
+
+    public function addToConvertQueue(string $dataSetId): array
+    {
+        return [];
+    }
+}

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

@@ -43,20 +43,25 @@ trait FilesUploadTrait
 
     protected function uploadFile(Request $request, UploadedFile $file): array
     {
+        $extension = $file->extension() ? $file->extension() : pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
+
         $pathname = $file->storeAs(
             sprintf("c%s/%s/%s", Auth::user()->company_id, $request->get("object_type"), date("Ymd")),
-            sprintf("%s.%s", md5(uniqid()), $file->extension())
+            sprintf("%s.%s", md5(uniqid()), $extension)
         );
 
         $data = [
             'bim' => [],
         ];
 
-        $extension = $file->extension() ? $file->extension() : pathinfo($file->getClientOriginalName(), PATHINFO_EXTENSION);
         $isBimFile = 0;
         if (in_array($extension, config("bim.extensions")) && $request->object_type == FileObjectType::CONTAINER->value) {
             $isBimFile = true;
-            $data['bim'] = BIMFactory::make()->uploadFile($file);
+            $data['bim'] = BIMFactory::make()->uploadFile($file, [
+                'pathname' => $pathname,
+                'extension' => $extension,
+                'is_cad' => in_array($extension, ['dwg', 'dwf', 'dws', 'dwt']),
+            ]);
         }
 
         throw_validation_if(! $pathname, "File upload failed.");

+ 1 - 0
composer.json

@@ -8,6 +8,7 @@
         "php": "^8.1",
         "doctrine/dbal": "*",
         "guzzlehttp/guzzle": "^7.2",
+        "iidestiny/laravel-filesystem-oss": "^3.1",
         "laravel/framework": "^10.10",
         "laravel/sanctum": "^3.3",
         "laravel/tinker": "^2.8",

+ 122 - 2
composer.lock

@@ -4,8 +4,43 @@
         "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
         "This file is @generated automatically"
     ],
-    "content-hash": "9e76908a58f1c11692d8918c4ac2bb5c",
+    "content-hash": "7634df1f9d366af84dd8e4ba22993dec",
     "packages": [
+        {
+            "name": "aliyuncs/oss-sdk-php",
+            "version": "v2.7.1",
+            "dist": {
+                "type": "zip",
+                "url": "https://mirrors.tencent.com/repository/composer/aliyuncs/oss-sdk-php/v2.7.1/aliyuncs-oss-sdk-php-v2.7.1.zip",
+                "reference": "ce5d34dae9868237a32248788ea175c7e9da14b1",
+                "shasum": ""
+            },
+            "require": {
+                "php": ">=5.3"
+            },
+            "require-dev": {
+                "php-coveralls/php-coveralls": "*",
+                "phpunit/phpunit": "*"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "OSS\\": "src/OSS"
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "Aliyuncs",
+                    "homepage": "http://www.aliyun.com"
+                }
+            ],
+            "description": "Aliyun OSS SDK for PHP",
+            "homepage": "http://www.aliyun.com/product/oss/",
+            "time": "2024-02-28T11:22:18+00:00"
+        },
         {
             "name": "brick/math",
             "version": "0.11.0",
@@ -1041,6 +1076,91 @@
             ],
             "time": "2023-12-03T19:50:20+00:00"
         },
+        {
+            "name": "iidestiny/flysystem-oss",
+            "version": "4.3",
+            "dist": {
+                "type": "zip",
+                "url": "https://mirrors.tencent.com/repository/composer/iidestiny/flysystem-oss/4.3/iidestiny-flysystem-oss-4.3.zip",
+                "reference": "15447c3367cb8a36a64bc2881c13ee2b6ae3fa26",
+                "shasum": ""
+            },
+            "require": {
+                "aliyuncs/oss-sdk-php": "^2.4",
+                "ext-curl": "*",
+                "ext-json": "*",
+                "ext-openssl": "*",
+                "league/flysystem": "^3.0",
+                "php": "^8.0.2"
+            },
+            "require-dev": {
+                "mockery/mockery": "^1.5",
+                "phpunit/phpunit": "^9.5",
+                "symfony/var-dumper": "^3.4"
+            },
+            "type": "library",
+            "autoload": {
+                "psr-4": {
+                    "Iidestiny\\Flysystem\\Oss\\": "src"
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "iidestiny",
+                    "email": "iidestiny@vip.qq.com"
+                }
+            ],
+            "description": "Flysystem adapter for the Oss storage.",
+            "keywords": [
+                "alioss",
+                "laravel",
+                "oss",
+                "阿里oss"
+            ],
+            "time": "2023-09-09T11:59:47+00:00"
+        },
+        {
+            "name": "iidestiny/laravel-filesystem-oss",
+            "version": "3.3",
+            "dist": {
+                "type": "zip",
+                "url": "https://mirrors.tencent.com/repository/composer/iidestiny/laravel-filesystem-oss/3.3/iidestiny-laravel-filesystem-oss-3.3.zip",
+                "reference": "30e788109accab282c106121bf1977754511e973",
+                "shasum": ""
+            },
+            "require": {
+                "iidestiny/flysystem-oss": "^4.1",
+                "laravel/framework": "^9.0 | ^10.0",
+                "php": "^8.0.2"
+            },
+            "type": "library",
+            "extra": {
+                "laravel": {
+                    "providers": [
+                        "Iidestiny\\LaravelFilesystemOss\\OssStorageServiceProvider"
+                    ]
+                }
+            },
+            "autoload": {
+                "psr-4": {
+                    "Iidestiny\\LaravelFilesystemOss\\": "src"
+                }
+            },
+            "license": [
+                "MIT"
+            ],
+            "authors": [
+                {
+                    "name": "iidestiny",
+                    "email": "iidestiny@vip.qq.com"
+                }
+            ],
+            "description": "Oss storage filesystem for Laravel.",
+            "time": "2023-08-25T03:00:39+00:00"
+        },
         {
             "name": "laravel/framework",
             "version": "v10.39.0",
@@ -7878,5 +7998,5 @@
         "php": "^8.1"
     },
     "platform-dev": [],
-    "plugin-api-version": "2.6.0"
+    "plugin-api-version": "2.3.0"
 }

+ 6 - 0
config/bim.php

@@ -11,5 +11,11 @@ return [
         'secret_key' => env("BLACK_HOLE_SECRET_KEY"),
         'user_id' => env("BLACK_HOLE_USER_ID"),
         'project_id' => env("BLACK_HOLE_PROJECT_ID"),
+    ],
+
+    'glendale' => [
+        'host' => env("GLENDALE_HOST", "http://43.139.250.80:18086/"),
+        'token' => env("GLENDALE_TOKEN"),
+        'project_id' => env("GLENDALE_PROJECT_ID"),
     ]
 ];

+ 9 - 1
config/filesystems.php

@@ -72,7 +72,15 @@ return [
                 'connect_timeout' => env('COS_CONNECT_TIMEOUT', 60),
             ],
         ],
-
+        'oss' => [
+            'driver' => 'oss',
+            'root' => '', // 设置上传时根前缀
+            'access_key' => env('OSS_ACCESS_KEY'),
+            'secret_key' => env('OSS_SECRET_KEY'),
+            'endpoint'   => env('OSS_ENDPOINT'), // 使用 ssl 这里设置如: https://oss-cn-beijing.aliyuncs.com
+            'bucket'     => env('OSS_BUCKET'),
+            'isCName'    => env('OSS_IS_CNAME', false), // 如果 isCname 为 false,endpoint 应配置 oss 提供的域名如:`oss-cn-beijing.aliyuncs.com`,否则为自定义域名,,cname 或 cdn 请自行到阿里 oss 后台配置并绑定 bucket
+        ],
     ],
 
     /*

+ 28 - 0
database/migrations/2024_05_15_194517_add_source_status_to_bim_files_table.php

@@ -0,0 +1,28 @@
+<?php
+
+use Illuminate\Database\Migrations\Migration;
+use Illuminate\Database\Schema\Blueprint;
+use Illuminate\Support\Facades\Schema;
+
+return new class extends Migration
+{
+    /**
+     * Run the migrations.
+     */
+    public function up(): void
+    {
+        Schema::table('bim_files', function (Blueprint $table) {
+            $table->string("source_status", 30)->nullable();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::table('bim_files', function (Blueprint $table) {
+            $table->dropColumn(['source_status']);
+        });
+    }
+};

+ 1 - 1
lang/ar/auth.php

@@ -3,8 +3,8 @@
 declare(strict_types=1);
 
 return [
+    'ban'      => 'المستخدم الحالي قد تم حظره من الدخول',
     'failed'   => 'بيانات الاعتماد هذه غير متطابقة مع البيانات المسجلة لدينا.',
     'password' => 'كلمة المرور غير صحيحة.',
     'throttle' => 'عدد كبير جدا من محاولات الدخول. يرجى المحاولة مرة أخرى بعد :seconds ثانية.',
-    'ban' => 'المستخدم الحالي قد تم حظره من الدخول',
 ];

+ 1 - 1
lang/en/auth.php

@@ -3,8 +3,8 @@
 declare(strict_types=1);
 
 return [
+    'ban'      => 'The current user has been blocked from logging in.',
     'failed'   => 'These credentials do not match our records.',
     'password' => 'The password is incorrect.',
     'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
-    'ban' => 'The current user has been blocked from logging in.',
 ];

+ 1 - 1
lang/zh_CN/auth.php

@@ -3,8 +3,8 @@
 declare(strict_types=1);
 
 return [
+    'ban'      => '当前用户已被禁止登录。',
     'failed'   => '用户名或密码错误。',
     'password' => '密码错误',
     'throttle' => '您尝试的登录次数过多,请 :seconds 秒后再试。',
-    'ban' => '当前用户已被禁止登录。',
 ];

+ 1 - 1
lang/zh_TW/auth.php

@@ -3,8 +3,8 @@
 declare(strict_types=1);
 
 return [
+    'ban'      => '當前用戶被禁止登錄。',
     'failed'   => '使用者名稱或密碼錯誤。',
     'password' => '密碼錯誤',
     'throttle' => '嘗試登入太多次,請在 :seconds 秒後再試。',
-    'ban' => '當前用戶被禁止登錄。',
 ];