上一篇,我们已经实现了浏览器将文件直传七牛云,但是在控制器中引入相关代码,冗长且繁琐。

于是,我今天抽空把前面那段代码优化了一下,原理是利用 Laravel 框架的 Macro 功能,为 Dcat\Admin\Form\Field\File 类添加一个名为 qiniu 方法。

打开 app/Admin/bootstrap.php 文件,添加如下代码:

use Dcat\Admin\Form\Field\File;
use Illuminate\Support\Facades\Storage;

// 扩展文件上传方法让浏览器直传七牛云
File::macro('qiniu', function (string $path, bool $saveFullUrl = true) {
    $path = trim($path, '/');

    // 文件保存路径(使用魔法变量)
    $saveKey = $path.'/$(etag)$(ext)';

    $disk = Storage::disk('qiniu');

    $policy = [
        'saveKey' => $saveKey,
        // 返回 Dcat 上传文件需要的报文格式
        'returnBody' => json_encode([
            'status' => true,
            'data' => [
                'id' => $saveFullUrl ? $disk->url($saveKey) : $saveKey,
            ],
        ]),
    ];

    // 七牛云上传 token
    $token = $disk->getAdapter()->uploadToken(null, 3600, $policy);

    $this->options([
        'fileVal' => 'file', // Dcat 默认为 _file_
        'server' => 'https://up-z1.qiniup.com', //上传地址
        'formData' => [
            'token' => $token, //添加 token
        ],
    ]);

    return $this;
});

方法 qiniu($path, $saveFullUrl) 第一个参数是文件保存目录,第2个参数表示是否返回完整URL,默认为是。关于代码中的魔法变量、server 地址,请查看上一篇文章说明。

示例,在控制器的 form 方法里使用:

protected function form()
{
    return Form::make(new Model(), function (Form $form) {

        // 返回完整URL
        $form->image('logo_url')
            ->autoUpload()
            ->qiniu('images/logo');

        // 只返回路径部分
        $form->image('logo_url')
            ->autoUpload()
            ->qiniu('images/logo', false);

    });
}

使用了这个 qiuniu( ) 方法,你可以忽略原来的 uniqueName( ) 和 saveFullUrl( ) 方法。