使用 Laravel Livewire 和 Filepond 处理文件上传和重新排序

问题描述

我的应用程序中有一个表单,允许用户创建帖子,同时将多张图片上传到正在创建的帖子中。

我正在使用 Laravel Livewire 和 Filepond 来实现这一点。

我遇到的问题是我需要允许用户重新排序图像(因为它是一个画廊并且顺序很重要),并在提交表单时将订单保存在数据库中。

我遇到的另一个问题是允许用户稍后编辑他们的帖子。我需要在 filepond 中加载他们预先存在的帖子图像,并允许他们上传更多、删除和/或重新排序。

用户保存帖子时,我需要能够更新我的数据库文件系统。

我几天来一直试图解决这个问题,但没有成功。在线所有信息都是关于如何上传文件,但没有关于如何重新排序或预先填充现有文件的信息。

对此的任何帮助将不胜感激。

这是我目前的代码供参考:

<div
    x-data=""
    x-init="
       
        FilePond.setoptions({
            allowMultiple: true,allowReorder: true,itemInsertLocation: 'after',server: {
                process: (fieldName,file,Metadata,load,error,progress,abort,transfer,options) => {
                    @this.upload('images',progress)
                },revert: (filename,load) => {
                    @this.removeUpload('images',filename,load)
                },load: (source,headers) => {
                    var myRequest = new Request(source);
                    fetch(myRequest).then(function(response) {
                      response.blob().then(function(myBlob) {
                        load(myBlob)
                      });
                    });
                },},});
        const pond = FilePond.create($refs.input,{
            acceptedFileTypes: ['image/png','image/jpeg'],maxFileSize: '7MB',allowImageCrop: true,allowImageResize: true,imageResizeTargetWidth: '1000px',imageResizeTargetHeight: '1000px',filePosterMaxHeight: '256px',files: {{ $existingImages }} // used for when editing a post and it already has images. see PHP component on how I set this variable
            
        });

    "
>
    <div wire:ignore wire:key="images">
        <div class="form-group text-center">
            <input
                id="image-upload"
                type="file"
                x-ref="input"
                multiple
                data-allow-reorder="true"
                data-max-file-size="3MB"
                data-max-files="10"
            >
        </div>
    </div>
</div>

我的 livewire PHP 组件:

    public $images = [];
    public $existingImages;

    public function mountMedia($post) {
        if($post){
            $this->existingImages = $post->images->map(function ($image) use ($post) {
                return [
                    'source' => $image->id,'options' => [
                        'type' => 'local','file' => [
                            'name' => $image->getUrl(),'size' => $image->file_size,'type' => $image->mime_type,],'Metadata' => [
                            'poster' => $image->getUrl(),'position' => $image->position
                        ],];

            });
        }
    }
    public function saveImage($file,$post,$position) {
        // Create a unique random string
        $randString = Str::random(3);
        // Get time
        $time = time();
        // Set file name
        $filename = $time. '-' . $randString.'-'.auth()->user()->id;
        $extension = '.'.$file->getClientOriginalExtension();

        // Save images for gallery 
        $regImage = $file->storeAs('/'. $post->id,$filename.$extension,'post_images');

           
        // Create a new image in db
        Image::create([
            'user_id'       => auth()->user()->id,'post_id'       => $post->id,'position'      => $position,'filename'      => $filename,'extension'     => $extension,'src'           => 'post_images','mime_type'     => $file->getMimeType(),'file_size'     => $file->getSize(),]);
    }

    public function saveMedia($post) {
        // Make sure user owns post
        abort_unless($post->user_id == auth()->user()->id,403);

        // Set default position
        $position = 1;

        // Save each image
        foreach ($this->images as $file) {
           $this->saveImage($file,$position);
            // Increment position for next image
            $position++;
        }
    }
}

解决方法

为了在 Livewire 中对项目进行排序,我会使用 https://github.com/livewire/sortable。 Sortable 非常易于使用。

对于 filepond,如果以后应该再次使用原始图像,我也会保存该图像以及与编辑版本的关系。