stechstudio/laravel-shuttle

这是我创建的包:laravel-shuttle

支持包维护!
stechstudio

安装: 907

依赖: 0

建议者: 0

安全: 0

星标: 0

关注者: 5

分支: 0

开放问题: 2

语言:Blade

v1.0.0 2022-07-12 20:14 UTC

README

此包旨在提供一个简单而令人惊叹的方法,在TALL应用程序中实现大规模文件上传,直接上传到S3。

  • 只需使用单个Blade组件集成到您的应用程序中,这就是全部。
  • UI就绪。您不需要在UI中实现任何内容。用户可以在页面的任何位置拖放文件,并且会显示一个固定在底部的进度条。
  • 当文件上传时,会触发事件,因此您的应用程序可以做出反应并相应地更新UI。

安装

1. 使用Composer安装此包

composer require stechstudio/laravel-shuttle

2. 迁移数据库

Shuttle会设置自己的uploads表以存储每个文件的详细信息。然后您的应用程序可以使用这些上传记录,或者您可以在上传完成后将文件信息移动到不同的数据库表中。

php artisan migrate

3. 添加路由

Shuttle将为多部分上传创建所有必要的路由,您只需告诉Shuttle在哪里定义路由即可。这样,您可以包装任何中间件、路由前缀或其他要求。

Route::middleware(['auth'])->group(function() {
    Shuttle::routes();
});

4. 配置AWS

确保您已经在Laravel中正确配置了一个s3磁盘。如果您想更改Shuttle使用的磁盘或S3客户端,请参阅下面的高级配置。

您决定使用的S3存储桶需要配置CORS。在AWS控制台中打开存储桶,点击权限选项卡,滚动到CORS框,并粘贴以下内容

[
    {
        "AllowedHeaders": [
            "*"
        ],
        "AllowedMethods": [
            "POST",
            "PUT",
            "DELETE"
        ],
        "AllowedOrigins": [
            "*"
        ],
        "ExposeHeaders": [
            "ETag"
        ],
        "MaxAgeSeconds": 3000
    }
]

如果您希望,可以进一步限制来源。

免责声明
CORS Everywhere插件与此包不兼容。请确保在本地开发时将其禁用。

实现

在您的应用程序中实现Shuttle非常简单,让我们一步一步来。

1. 实现Blade组件

是时候将Shuttle应用到您的应用程序中了。您只需在视图中使用Blade组件,以便用户可以上传文件。这应该是一个Livewire视图文件。

<x-shuttle::uploader />

2. 添加上传上下文

您的Livewire组件需要公开一个$uploadContext数组,其中包含有关上传文件的所有元数据,这些元数据将在以后用于确定所有权。

例如,假设您有一个简单的文件夹/文件应用程序。当用户上传文件到,您将需要将文件夹ID添加到每个文件上传中,以便可以在数据库中确定如何关联文件。您的Folder Livewire组件类可能看起来像这样

class Folder extends Component {
    public $uploadContext = [];
    public $folder;

    public function mount(Folder $folder) {
        $this->folder = $folder;
        $this->uploadContext = ['folder_id' => $folder->id];    
    }

3. 告诉Shuttle如何关联文件

当文件上传时,Shuttle需要知道文件的所有者。我们不是指执行上传的用户,而是指文件应附加到的模型。这通常是文件夹或项目。

在您的AppServiceProviderboot()方法中,您将需要定义一个回调函数,该函数接收文件元数据(包括前一步中提供的上下文信息)。这将返回一个数据库模型。

因此,对于上面的文件夹示例,我们可能定义一个回调函数如下

Shuttle::resolveOwnerWith(function(array $metadata) {
    return Folder::findOrFail($metadata['folder_id']);
});

Shuttle现在将确保上传的文件具有设置为该文件夹的owner关系。

您还需要在拥有者模型上添加HasUploads特性。在我们的示例中,这将是Folder模型。

警告
这是一个基本示例,用于使事物运行。您很可能会在回调函数中执行一些授权检查,以确保当前登录的用户有权将文件上传到指定的文件夹。

4. 将关系添加到您的拥有者模型,或者自己处理完成的上传

如果您想直接使用uploads数据库记录,就没有什么需要做的了。您可以使用我们的上一个示例设置,通过$folder->uploads访问,并检索所有已上传的文件。

或者,如果您希望自己处理上传文件的数据,可以设置一个回调,Shuttle在上传完成后执行。在您的AppServiceProvider中这样做

Shuttle::whenComplete(function(Upload $upload) {
    // ...store the upload information somewhere else in your database
});

在这种情况下,您可能希望将Upload记录视为临时文件,并在处理完上述回调后执行$upload->delete()

上传文件

到目前为止,您应该能够访问到您实现Shuttle Blade组件的应用程序页面,并在Livewire组件中提供上传上下文。

将一些文件拖放到页面上,应该会看到一个半透明的覆盖层出现,告诉您可以放下您的文件。

一旦放下文件,您应该在页面底部看到一个条形图,显示上传的状态。您可以展开这个条形图,查看每个文件的上传状态。

当所有放下文件成功上传时,条形图会变成绿色。如果任何上传失败,它会变成红色并自动展开,显示错误消息。

事件

我们公开以下您可以监听的事件。

定制

您能够定制UI的颜色。您只需发布配置文件即可。

php artisan vendor:publish --tag=shuttle-config

<?php

declare(strict_types=1);

return [

    /**
     * The URL endpoint used to trigger the
     * upload process.
     */
    'url_prefix' => '/uploader',

    /**
     * The disk you want to use for file uploads. This
     * must be a disk that uses the S3 driver.
     */
    'disk' => 's3',

    /**
     * The authentication guard used for authorization.
     */
    'guard' => 'web',

    /**
     * The background colors used for the file uploader UI.
     * You can customise the color for each state. You can
     * use any valid Tailwind background class. If you
     * need to specify a custom HEX value, create a
     * new color variable in your Tailwind config
     * file. Custom HEX values are not compiled
     * at run time.
     */
    'colors' => [

        'details-panel' => [
            'uploading' => env(key: 'DETAILS_PANEL_UPLOADING', default: 'bg-blue-500'),

            'upload-success' => env(key: 'DETAILS_PANEL_UPLOAD_SUCCESS', default: 'bg-green-500'),

            'upload-error' => env(key: 'DETAILS_PANEL_UPLOAD_ERROR', default: 'bg-red-500'),
        ],

    ],

];

CSRF令牌

您需要将以下内容添加到您的VerifyCsrfToken中间件中,以防止CSRF令牌不匹配错误。

    protected $except = [
        'upload/sign/*',
        '*uploader/s3/multipart*'
    ];