跳到主要内容
版本:3.x

文件上传

概述

文件上传(FileUpload)字段是基于 Filepond 的。

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
File upload

Filament 也支持 spatie/laravel-medialibrary。更多详情请查阅插件文档

配置存储磁盘和存储目录

默认情况下,文件会公开上传到配置文件中定义的存储盘。你也可以设置 FILAMENT_FILESYSTEM_DISK 环境变量对此进行修改。

要正确预览图片及其他文件,FilePond 要求将文本保存到与应用相同的域名中,或者设置合适的 CORS 头。请确保 APP_URL 环境变量设置正确;或者修改文件系统(filesystem)驱动,设置成正确的 URL。如果文件托管到另外的域名,比如 S3,请确保设置了 CORS 头部。

要为特定字段修改磁盘和目录以及文件的可见度,请使用 disk()directory()visibility() 方法:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->disk('s3')
->directory('form-attachments')
->visibility('private')

是否从磁盘中删除这些文件由开发者决定,因为 Filament 无从知晓这些图片是否由其他地方的依赖。其中一种自动实现方式是监测模型事件

多文件上传

你也可以上传多个文件。URL 以 JSON 格式存储:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()

如果你使用 Eloquent 来保存文件 URL,请确保将 array [cast] 添加到对应的模型属性中:

use Illuminate\Database\Eloquent\Model;

class Message extends Model
{
protected $casts = [
'attachments' => 'array',
];

// ...
}

控制文件名

默认情况下,新上传的文件会生成随机文件名。这是为了确保不会和现有的文件产生冲突。

保留原始文件名

使用 preserveFilenames() 方法,可以保留上传文件的原始文件名:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->preserveFilenames()

生成自定义文件名

使用 getUploadedFileNameForStorageUsing() 方法,你可以完全自定义文件名的生成方式,并基于上传的文件 Sfile 在闭包中返回字符串:

use Livewire\Features\SupportFileUploads\TemporaryUploadedFile;

FileUpload::make('attachment')
->getUploadedFileNameForStorageUsing(
fn (TemporaryUploadedFile $file): string => (string) str($file->getClientOriginalName())
->prepend('custom-prefix-'),
)

将原始文件名单独存储

使用 storeFileNamesIn() 方法,你可以保留随机生成的文件名的同时,将原始文件名存储起来:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->storeFileNamesIn('attachment_file_names')

attachment_file_names 现在将会存储上传文件的原始文件名,在表单提交后将其存入到数据库中。如果通过 multiple() 实现多文件上传,请确保将 array [cast] 添加到该 Eloquent 模型属性中。

头像模式

使用 avatar() 方法,你可以为上传文件启用头像模式:

use Filament\Forms\Components\FileUpload;

FileUpload::make('avatar')
->avatar()

这只允许上传图片,并且在上传后它将会在一个紧凑的圆中展示图片,这很适合于头像。

该特性与圆形裁切是绝佳匹配。

图片编辑器

你可以使用 imageEditor() 方法,为文件上传字段启用图片编辑器:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageEditor()

当你通过点击铅笔图标上传图片时,你可以打开该编辑器。你也可以在现有图片上点击铅笔图标打开图片编辑器,这将在保存时删除并重新上传图片。

允许用户按长宽比裁切图片

使用 imageEditorAspectRatios() 方法,你可以允许用户按照一套指定的长宽比裁切图片:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageEditor()
->imageEditorAspectRatios([
'16:9',
'4:3',
'1:1',
])

传入 null 作为选项,你也可以允许用户不选择长宽比:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageEditor()
->imageEditorAspectRatios([
null,
'16:9',
'4:3',
'1:1',
])

设置图片编辑器模式

使用 imageEditorMode() 方法,你可以修改图片编辑器模式,该方法可接收 123 作为参数。这些选项的解释可以在 Cropper.js 文档中查看:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageEditor()
->imageEditorMode(2)

自定义图片编辑器的空填充色

默认情况下,图片编辑器会使图片周围的空白区域透明。使用 imageEditorEmptyFillColor() 方法可以自定义空白区域的填充色:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageEditor()
->imageEditorEmptyFillColor('#000000')

设置图片编辑器的视窗大小

使用 imageEditorViewportWidth()imageEditorViewportHeight() 方法可以修改图片编辑器的视窗,在跨设备中使用会生成长宽比:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageEditor()
->imageEditorViewportWidth('1920')
->imageEditorViewportHeight('1080')

允许用户将图片裁切成圆

使用 circleCropper() 方法,可以允许用户将图片裁切成圆:

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->avatar()
->imageEditor()
->circleCropper()

这与 avatar() 方法完美结合,其以紧凑的圆形布局渲染图像。

不使用编辑器裁切和调整图标大小

Filepond 允许你在上传之前,在不需要编辑器的情况下,裁切图片及调整图片大小。你可以使用 imageCropAspectRatio()imageResizeTargetHeight()imageResizeTargetWidth() 方法自定义这些行为。应该为这三个方法设置 imageResizeMode(), 可设置成 forcecovercontain 三者其中之一。

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()
->imageResizeMode('cover')
->imageCropAspectRatio('16:9')
->imageResizeTargetWidth('1920')
->imageResizeTargetHeight('1080')

修改文件上传区域的外观

你也可以修改 Filepond 组件的通用外观。这些方法的可用选项可以在 Filepond 网站中查看。

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->imagePreviewHeight('250')
->loadingIndicatorPosition('left')
->panelAspectRatio('2:1')
->panelLayout('integrated')
->removeUploadedFileButtonPosition('right')
->uploadButtonPosition('left')
->uploadProgressIndicatorPosition('left')

文件重新排序

使用 reorderable() 方法,你可以允许用户对上传文件重新排序:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->reorderable()

使用该方法时,FilePond 可能将新上传的文件放到列表前面,而不是尾部。要对此进行修改,请使用 appendFiles() 方法:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->reorderable()
->appendFiles()

在新标签页中打开文件

使用 openable() 方法,你可以添加一个按钮,用来在新标签页中打开每个文件:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->openable()

下载文件

使用 downloadable() 方法,你可以为每个文件添加一个下载按钮:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->downloadable()

预览文件

默认情况下,有些文件类型可以在 FilePond 中预览中。如果你想禁用所有文件的预览,你可以使用 previewable(false) 方法:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->previewable(false)

表单提交时移动文件而不是复制文件

默认情况下,文件最初上传到 Livewire 的临时存储目录,然后在表单提交后将其复制到目标目录。如果你希望移动文件,加入上传的临时文件和永久文件存储在同一个磁盘上,你可以使用 moveFiles() 方法:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->moveFiles()

防止文件被永久存储

如果你想在表单提交时,阻止文件被永久存储,你可以使用 storeFiles(false) 方法:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->storeFiles(false)

表单提交后,会返回临时文件上传对象,而不是持久化的文件存储路径。这非常适合像导入的 CSV 这样的临时文件。

请注意,图片、视频和音频文件不会再表单预览中展示存储的文件名,除非你使用了 previewable(false)。这是因为 FilePond 预览插件的限制。

根据 EXIF 数据确定图像的方向

默认情况下,FilePond 会根据 EXIF 数据自动确定图片方向。使用 orientImagesFromExif(false) 方法,你可以禁用该行为:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->orientImagesFromExif(false)

隐藏移除文件按钮

使用 deletable(false),可以隐藏移除已上传的文件按钮:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->deletable(false)

阻止文件信息获取

表单加载后,会自动检测文件是否存在、文件大小和文件类型。这些都在后台实现。当使用具有许多文件的远程存储时,这一操作可能会消耗许多时间,你可以使用 fetchFileInformation(false) 方法禁用该特性:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->fetchFileInformation(false)

自定义上传消息

使用 uploadingMessage() 方法,你可以自定义显示在表单提交按钮中的上传消息:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->uploadingMessage('Uploading attachment...')

文件上传验证

除了验证页面中列出的所有规则之外,还有一些其他专用于文件上传的验证规则。

由于 Filament 是由 Livewire 驱动并使用其文件系统,因此你也需要参考 config/livewire.php 文件中的默认文件上传验证规则。这也控制了最大 12MB 的文件大小。

文件类型验证

使用 acceptedFileTypes(),并在其中传入一个 MIME 类型数组,你可以限制上传的文件类型:

use Filament\Forms\Components\FileUpload;

FileUpload::make('document')
->acceptedFileTypes(['application/pdf'])

你也可以使用 image() 作为简写,以允许所有图片 MIME 类型。

use Filament\Forms\Components\FileUpload;

FileUpload::make('image')
->image()

文件大小验证

你也可以限制上传文件的大小,以 KB 计:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachment')
->minSize(512)
->maxSize(1024)

文件数量验证

使用 minFiles()maxFiles() 方法,你可以自定义可以上传的文件数量:

use Filament\Forms\Components\FileUpload;

FileUpload::make('attachments')
->multiple()
->minFiles(2)
->maxFiles(5)