FastAdmin 后台管理页面上传文件时使用的是插件 dropzone.js
进行文件上传。如果需要将上传的文件同时存入本地磁盘和七牛云,可以采取以下方案:
- 自定义上传类
在自己的应用中创建一个上传类,可以继承 think\file\UploadedFile
类,重写 move()
方法,实现另存一份到本地磁盘,再将另一份上传到七牛云的逻辑。
例如,假设我们自定义了一个 LocalQiniuFile
类:
<?php
namespace app\index\library;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use think\file\UploadedFile;
use think\facade\Config;
class LocalQiniuFile extends UploadedFile
{
/**
* 保存文件
* @param string $path
* @param string $savename
* @param bool $replace
* @return bool|string
* @throws \Exception
*/
public function move($path, $savename = '', $replace = true)
{
$savename = $this->getSaveName($savename);
$disk = Config::get('filesystem.disks.qiniu');
if (!$disk) {
throw new \Exception('无法加载七牛云的配置');
}
// 先另存一份到本地磁盘
parent::move($path, $savename, $replace);
// 上传到七牛云
$auth = new Auth($disk['access_key'], $disk['secret_key']);
$token = $auth->uploadToken($disk['bucket']);
$uploadManager = new UploadManager();
list($ret, $err) = $uploadManager->putFile($token, $savename, $this->getRealPath());
// 如果上传到七牛云失败,则抛出异常
if ($err) {
throw new \Exception('上传到七牛云失败:' . $err->message());
}
// 返回另存一份到本地磁盘的文件路径
return $path . DIRECTORY_SEPARATOR . $savename;
}
}
在 move()
方法中,我们先使用 parent::move()
方法另存一份到本地磁盘,然后再将另一个文件上传到七牛云。
- 覆盖请求类
FastAdmin 后台管理页面的文件上传请求数据可以通过更改 window.Dropzone.prototype.defaultOptions
对象来修改默认设置。我们可以在 FastAdmin 的 public/static/js/adm/view.js
中重写 Dropzone.autoDiscover
和 Dropzone.prototype.defaultOptions
对象。
例如,我们需要覆盖上传文件的请求头部信息,其中需要添加一个类似于 X-Save-To: local
的请求头部,表示同时将文件保存到本地磁盘上:
Dropzone.autoDiscover = false;
Dropzone.prototype.defaultOptions = {
// 重写headers,添加X-Save-To请求头部
headers: {
"X-Save-To": "local"
},
// 省略其他设置
};
这样,我们在上传文件时就可以将文件同时保存到本地磁盘上。可以在自己的控制器中通过以下代码获取上传文件的路径:
use app\index\library\LocalQiniuFile;
use think\Request;
class Upload extends \think\Controller
{
public function index(Request $request)
{
$file = new LocalQiniuFile('file');
$path = $file->move('upload');
return $this->success('上传成功', ['path' => $path]);
}
}
需要注意的是,因为我们在上传文件时使用了自定义的请求头部,所以在后端处理上传文件时需要对请求头部进行判断,如果包含有 X-Save-To: local
的请求头部,则将文件保存到本地磁盘中。