Browse Source

导入异常封装&需求导入

moell 8 months ago
parent
commit
cb5324625d

+ 1 - 1
app/Exceptions/Handler.php

@@ -33,6 +33,6 @@ class Handler extends ExceptionHandler
             };
         });
 
-        $this->renderable(fn(ValidationException $e) => $this->unprocesableEtity(message: $e->getMessage()));
+        $this->renderable(fn(ValidationException $e) => $this->unprocesableEtity($e->getErrors(), message: $e->getMessage()));
     }
 }

+ 11 - 0
app/Exceptions/ValidationException.php

@@ -2,7 +2,18 @@
 
 namespace App\Exceptions;
 
+
+use JetBrains\PhpStorm\Internal\LanguageLevelTypeAware;
+
 class ValidationException extends \Exception
 {
+    public function __construct(string $message = "", int $code = 0, ?Throwable $previous = null, protected array $errors = [])
+    {
+        parent::__construct($message, $code, $previous);
+    }
 
+    public function getErrors(): array
+    {
+        return $this->errors;
+    }
 }

+ 9 - 0
app/Http/Controllers/API/RequirementController.php

@@ -11,6 +11,7 @@ use App\Http\Requests\API\Requirement\LinkPlanRequest;
 use App\Http\Requests\API\Requirement\BatchCreateRequest;
 use App\Http\Resources\API\AssetRequirementResource;
 use App\Http\Resources\API\RequirementResource;
+use App\Imports\RequirementImport;
 use App\Models\Asset;
 use App\Models\Enums\ActionObjectType;
 use App\Models\Enums\FileObjectType;
@@ -24,6 +25,7 @@ use App\Services\History\ModelChangeDetector;
 use Illuminate\Http\Request;
 use Illuminate\Support\Facades\Auth;
 use Illuminate\Support\Facades\DB;
+use Maatwebsite\Excel\Facades\Excel;
 
 class RequirementController extends Controller
 {
@@ -228,4 +230,11 @@ class RequirementController extends Controller
         });
         return $this->created();
     }
+
+    public function import(Request $request)
+    {
+        Excel::import(new RequirementImport(), $request->file("file"));
+
+        return $this->created();
+    }
 }

+ 31 - 0
app/Imports/ImportValidatorHelper.php

@@ -0,0 +1,31 @@
+<?php
+
+namespace App\Imports;
+
+use App\Http\Controllers\JsonResponseHelper;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Validator;
+
+trait ImportValidatorHelper
+{
+    use JsonResponseHelper;
+
+    protected function validatorByCollection(Collection $collection, array $rules, array $messages = [])
+    {
+        $errors = [];
+        foreach ($collection as $index => $item) {
+            $validator = Validator::make($item->toArray(), $rules, $messages);
+
+            if ($validator->fails()) {
+                $errors[$index + 1] = [
+                    'index' => $index + 1,
+                    'errors' => $validator->errors()->all()
+                ];
+            }
+        }
+
+        if ($errors) {
+            throw new \App\Exceptions\ValidationException(errors: array_values($errors));
+        }
+    }
+}

+ 42 - 0
app/Imports/RequirementImport.php

@@ -0,0 +1,42 @@
+<?php
+
+namespace App\Imports;
+
+use App\Http\Requests\API\Requirement\CreateOrUpdateRequest;
+use App\Models\Enums\ObjectAction;
+use App\Models\Requirement;
+use App\Repositories\ActionRepository;
+use Illuminate\Support\Collection;
+use Illuminate\Support\Facades\Auth;
+use Maatwebsite\Excel\Concerns\ToCollection;
+use Maatwebsite\Excel\Concerns\WithHeadingRow;
+
+class RequirementImport implements ToCollection, WithHeadingRow
+{
+    use ImportValidatorHelper;
+
+    public function collection(Collection $collection): void
+    {
+        $this->validatorByCollection($collection, (new CreateOrUpdateRequest())->rules());
+
+        foreach ($collection as $item) {
+            $requirement = new Requirement();
+
+            $requirement->mergeFillable([
+                'company_id', 'created_by',
+            ]);
+
+            $requirement->fill([
+                ...$item->toArray(),
+                'company_id' => Auth::user()->company_id,
+                'created_by' => Auth::id(),
+                'mailto' => [],
+            ]);
+            $requirement->save();
+
+            ActionRepository::createRequirement(
+                $requirement, ObjectAction::CREATED
+            );
+        }
+    }
+}

+ 2 - 2
app/Services/Notification/ActionEmail/ActionEmailService.php

@@ -67,12 +67,12 @@ class ActionEmailService
 
     protected function container(Container $container)
     {
-        $this->dispatch($container->mailto, new ContainerAction($container, $this->objectAction, $this->actions));
+        $this->dispatch($container->mailto ?? [], new ContainerAction($container, $this->objectAction, $this->actions));
     }
 
     protected function requirement(Requirement $requirement)
     {
-        $this->dispatch($requirement->mailto, new RequirementAction($requirement, $this->objectAction, $this->actions));
+        $this->dispatch($requirement->mailto ?? [], new RequirementAction($requirement, $this->objectAction, $this->actions));
     }
 
     protected function task(Task $task)

+ 1 - 0
routes/api.php

@@ -101,6 +101,7 @@ Route::middleware(['auth:sanctum','account.limit'])->group(function () {
         Route::patch("requirement/{plan_id}/plan", [API\RequirementController::class, "linkPlan"])->name("requirement.linkPlan");
         Route::patch("requirement/plan/unlink", [API\RequirementController::class, "unlinkPlan"])->name("requirement.unlinkPlan");
         Route::get("requirement-export", [API\RequirementController::class, "export"])->name("requirement.export");
+        Route::post("requirement-import", [API\RequirementController::class, "import"])->name("requirement.import");
 
         Route::get("project-tree",[API\ProjectController::class, 'tree'])->name('project.tree');
         Route::get("project/{project}/dynamic", [API\ProjectController::class, "dynamic"])->name("project.dynamic");