Browse Source

container create

moell 11 months ago
parent
commit
ea7eec57bb

+ 91 - 0
app/Http/Controllers/API/ContainerController.php

@@ -0,0 +1,91 @@
+<?php
+
+namespace App\Http\Controllers\API;
+
+use App\Http\Controllers\Controller;
+use App\Http\Requests\API\Container\CreateOrUpdateRequest;
+use App\Models\Container;
+use App\Models\Enums\FileObjectType;
+use App\Models\Enums\ObjectAction;
+use App\Repositories\ActionRepository;
+use App\Repositories\CustomFieldRepository;
+use App\Services\File\FileAssociationService;
+use App\Services\File\ImageUrlService;
+use Illuminate\Http\Request;
+use Illuminate\Support\Facades\Auth;
+
+class ContainerController extends Controller
+{
+    /**
+     * Display a listing of the resource.
+     */
+    public function index()
+    {
+        //
+    }
+
+    /**
+     * Store a newly created resource in storage.
+     */
+    public function store(
+        CreateOrUpdateRequest $request,
+        ImageUrlService $imageUrlService,
+        FileAssociationService $service,
+        CustomFieldRepository $customFieldRepo
+    )
+    {
+        $formData = [
+            ...$request->all(),
+            'company_id' => Auth::user()->company_id,
+            'created_by' => Auth::id(),
+            'whitelist' => $request->whitelist ? sprintf(",%s,", implode(',', $request->whitelist)) : null,
+            'description' => $imageUrlService->interceptImageUrl($request->description) ,
+        ];
+
+        if ($request->has("naming_rule_id") && $request->get("naming_rule_id") > 0) {
+            $keys = $customFieldRepo->keysByGroup($request->get("naming_rule_id"));
+            $formData['naming_rules'] = $request->only($keys);
+        }
+
+        $container = new Container();
+        $container->mergeFillable(['company_id']);
+        $container->fill($formData);
+        $container->save();
+
+        $container = Container::query()->create($formData);
+
+        ActionRepository::createByContainer($container, ObjectAction::CREATED);
+
+        $service->association(
+            $request->get("file_ids", []),
+            $container->id,
+            FileObjectType::CONTAINER
+        );
+
+        return $this->created();
+    }
+
+    /**
+     * Display the specified resource.
+     */
+    public function show(string $id)
+    {
+        //
+    }
+
+    /**
+     * Update the specified resource in storage.
+     */
+    public function update(Request $request, string $id)
+    {
+        //
+    }
+
+    /**
+     * Remove the specified resource from storage.
+     */
+    public function destroy(string $id)
+    {
+        //
+    }
+}

+ 66 - 0
app/Http/Requests/API/Container/CreateOrUpdateRequest.php

@@ -0,0 +1,66 @@
+<?php
+
+namespace App\Http\Requests\API\Container;
+
+use App\Http\Requests\CustomFieldRuleHelper;
+use App\Http\Requests\NamingRuleHelper;
+use App\Http\Requests\RuleHelper;
+use App\Models\Enums\ContainerACL;
+use Illuminate\Foundation\Http\FormRequest;
+use Illuminate\Support\Facades\Auth;
+use Illuminate\Validation\Rule;
+use Illuminate\Validation\Rules\Enum;
+
+class CreateOrUpdateRequest extends FormRequest
+{
+    use RuleHelper, CustomFieldRuleHelper, NamingRuleHelper;
+
+    /**
+     * Determine if the user is authorized to make this request.
+     */
+    public function authorize(): bool
+    {
+        return true;
+    }
+
+    /**
+     * Get the validation rules that apply to the request.
+     *
+     * @return array<string, \Illuminate\Contracts\Validation\ValidationRule|array<mixed>|string>
+     */
+    public function rules(): array
+    {
+        $rules =  [
+            'library_id' => [
+                'required',
+                Rule::exists('libraries', 'id')->where($this->userCompanyWhere()),
+            ],
+            'naming_rule_id' => [
+                Rule::when($this->get('naming_rule_id') > 0, [
+                    Rule::exists('naming_rules', 'id')->whereIn('company_id', [
+                        0, Auth::user()->company_id,
+                    ]),
+                ])
+            ],
+            'name' => 'required|max:150',
+            'email_subject' => 'max:255',
+            'acl' => [
+                new Enum(ContainerACL::class),
+            ],
+            'whitelist' => $this->usersCompanyRules(),
+            'mailto' => $this->usersCompanyRules(),
+        ];
+
+        $containerRules = $this->customFieldRuleByGroup("container", ['doc_type', 'doc_stage']);
+
+        if ($this->has("naming_rule_id") && $this->get("naming_rule_id") > 0) {
+            $this->namingRuleCheck($this->get("naming_rule_id"));
+
+            $namingRules = $this->customFieldRuleByGroup($this->get("naming_rule_id"));
+
+            $rules = [...$rules, ... $namingRules];
+        }
+
+        return [...$containerRules, ...$rules];
+    }
+}

+ 16 - 0
app/ModelFilters/ContainerFilter.php

@@ -0,0 +1,16 @@
+<?php 
+
+namespace App\ModelFilters;
+
+use EloquentFilter\ModelFilter;
+
+class ContainerFilter extends ModelFilter
+{
+    /**
+    * Related Models that have ModelFilters as well as the method on the ModelFilter
+    * As [relationMethod => [input_key1, input_key2]].
+    *
+    * @var array
+    */
+    public $relations = [];
+}

+ 32 - 0
app/Models/Container.php

@@ -0,0 +1,32 @@
+<?php
+
+namespace App\Models;
+
+use App\Models\Scopes\CompanyScope;
+use Illuminate\Database\Eloquent\Factories\HasFactory;
+use Illuminate\Database\Eloquent\Model;
+
+class Container extends Model
+{
+    use HasFactory;
+
+    protected $fillable = [
+        'name', 'library_id', 'naming_rule_id', 'naming_rules', 'mailto', 'email_subject', 'acl', 'whitelist',
+        'description', 'doc_stage', 'doc_type'
+    ];
+
+    protected $casts = [
+        'mailto' => 'array',
+        'naming_rules' => 'array',
+    ];
+
+    protected static function booted(): void
+    {
+        static::addGlobalScope(new CompanyScope);
+    }
+
+    public function library(): \Illuminate\Database\Eloquent\Relations\BelongsTo
+    {
+        return $this->belongsTo(Library::class, "library_id");
+    }
+}

+ 2 - 0
app/Models/Enums/ActionObjectType.php

@@ -23,6 +23,8 @@ enum ActionObjectType: string
 
     case PLAN = "plan";
 
+    case CONTAINER = "container";
+
     public function modelBuilder(): \Illuminate\Database\Eloquent\Builder
     {
         return match ($this) {

+ 10 - 0
app/Models/Enums/ContainerACL.php

@@ -0,0 +1,10 @@
+<?php
+
+namespace App\Models\Enums;
+
+enum ContainerACL: string
+{
+    case PRIVATE = 'private';
+
+    case CUSTOM = 'custom';
+}

+ 2 - 0
app/Models/Enums/FileObjectType.php

@@ -23,6 +23,8 @@ enum FileObjectType: string
 
     case PLAN = "plan";
 
+    case CONTAINER = "container";
+
     public function modelBuilder(): \Illuminate\Database\Eloquent\Builder
     {
         return match ($this) {

+ 20 - 0
app/Repositories/ActionRepository.php

@@ -4,6 +4,7 @@ namespace App\Repositories;
 
 use App\Events\ObjectActionCreate;
 use App\Models\Action;
+use App\Models\Container;
 use App\Models\Enums\ActionObjectType;
 use App\Models\Enums\ObjectAction;
 use App\Models\History;
@@ -108,6 +109,25 @@ class ActionRepository
         );
     }
 
+    public static function createByContainer(
+        Container    $container,
+        ObjectAction $action,
+        string       $comment = null,
+        array        $extraFields = [],
+        array        $objectChanges = [],
+    ): \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Builder
+    {
+        return self::create(
+            $container->id,
+            ActionObjectType::CONTAINER,
+            $action,
+            $container->library?->project_id,
+            $comment,
+            $extraFields,
+            $objectChanges,
+        );
+    }
+
     public static function latestDynamic(Project $project)
     {
         $actions = Action::query()

+ 6 - 1
app/Services/File/ImageUrlService.php

@@ -16,7 +16,12 @@ use Illuminate\Support\Str;
 
 class ImageUrlService
 {
-    public function interceptImageUrl(string $comment){
+    public function interceptImageUrl(string $comment): bool|string|null
+    {
+        if (! $comment) {
+            return null;
+        }
+
         $newComment = null;
         $dom = new DOMDocument();
         libxml_use_internal_errors(true); // 禁用错误报告

+ 41 - 0
database/migrations/2024_04_14_105925_create_containers_table.php

@@ -0,0 +1,41 @@
+<?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::create('containers', function (Blueprint $table) {
+            $table->id();
+            $table->string("name", 150);
+            $table->integer("company_id");
+            $table->integer("library_id")->nullable();
+            $table->integer("naming_rule_id")->nullable();
+            $table->string("doc_stage", 50)->nullable();
+            $table->string("doc_type", 50)->nullable();
+            $table->json("naming_rules")->nullable();
+            $table->json('mailto')->nullable();
+            $table->string('email_subject')->nullable();
+            $table->string('acl')->default('private')->comment('private,custom');
+            $table->string("whitelist")->nullable();
+            $table->text("description")->nullable();
+            $table->integer("created_by")->nullable();
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('containers');
+    }
+};

+ 35 - 0
database/migrations/2024_04_14_124847_create_documents_table.php

@@ -0,0 +1,35 @@
+<?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::create('documents', function (Blueprint $table) {
+            $table->id();
+            $table->string("name", 150);
+            $table->integer("container_id");
+            $table->integer("folder_id");
+            $table->text("content")->nullable();
+            $table->tinyInteger("source")->default(1)->comment("1-系统文档;2-外部上传");
+            $table->integer("file_id")->nullable()->comment("上传文档文件ID");
+            $table->integer("created_by")->nullable();
+            $table->softDeletes();
+            $table->timestamps();
+        });
+    }
+
+    /**
+     * Reverse the migrations.
+     */
+    public function down(): void
+    {
+        Schema::dropIfExists('documents');
+    }
+};

+ 1 - 0
routes/api.php

@@ -50,6 +50,7 @@ Route::middleware(['auth:sanctum'])->group(function () {
             'library' => API\LibraryController::class,
             'department' => API\DepartmentController::class,
             'user' => API\UserController::class,
+            'container' => API\ContainerController::class,
         ]);
         Route::apiResource("company", API\CompanyController::class)->only([
             'index', 'show'