up.
This commit is contained in:
parent
f9631ff92f
commit
f674435b25
@ -8,6 +8,7 @@ use app\service\CurdService;
|
||||
use think\db\exception\DbException;
|
||||
use think\exception\FileException;
|
||||
use think\exception\ValidateException;
|
||||
use think\facade\Filesystem;
|
||||
use think\response\Json;
|
||||
|
||||
class FileController extends BaseController
|
||||
|
||||
@ -1,18 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace app\entity;
|
||||
|
||||
/**
|
||||
* 上传文件实体类
|
||||
*/
|
||||
class UploadFile
|
||||
{
|
||||
private \think\File $file;
|
||||
private SysFileRecord $record;
|
||||
|
||||
public function done(\think\File $file, SysFileRecord $record)
|
||||
{
|
||||
$this->file = $file;
|
||||
$this->record = $record;
|
||||
}
|
||||
}
|
||||
21
app/entity/file/UploadResult.php
Normal file
21
app/entity/file/UploadResult.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace app\entity\file;
|
||||
|
||||
|
||||
/**
|
||||
* 上传文件结果实体类
|
||||
*/
|
||||
readonly class UploadResult
|
||||
{
|
||||
public string $url;
|
||||
public string $path;
|
||||
public int $time;
|
||||
|
||||
public function __construct(array $data = [])
|
||||
{
|
||||
foreach ($data as $key => $value) {
|
||||
$this->$key = $value;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,8 @@ use app\BaseModel;
|
||||
* @property string $path_rule 路径规则
|
||||
* @property string $name_rule 命名规则
|
||||
* @property string $query Query参数携带
|
||||
* @property int $is_close 是否关闭上传权限
|
||||
* @property string $url 自定义预览URL
|
||||
* @property string $permissions
|
||||
* #1 文件大小限制(单位:KB)
|
||||
* @property int $rule_file_size_limit_min
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
|
||||
namespace app\service;
|
||||
|
||||
use app\entity\file\UploadFile;
|
||||
use app\entity\SysFileRecord;
|
||||
use app\entity\SysFileRule;
|
||||
use app\entity\UploadFile;
|
||||
use app\service\file\FilesystemService;
|
||||
use think\File;
|
||||
use think\Service;
|
||||
@ -22,29 +22,29 @@ class FileService extends Service
|
||||
$this->app->bind('filesystem', FilesystemService::class);
|
||||
}
|
||||
|
||||
public function upload(string $contextId, File $file, SysFileRule $rule): UploadFile
|
||||
{
|
||||
$sysFileRecord = new SysFileRecord;
|
||||
// 存储规则相关
|
||||
$sysFileRecord->set('rid', $rule->id); // ruleId
|
||||
$sysFileRecord->set('disk', $rule->disk); // 存储disk
|
||||
// 文件信息相关
|
||||
$sysFileRecord->set('path', ''); // 文件存储路径
|
||||
$sysFileRecord->set('name', ''); // 文件名称
|
||||
$sysFileRecord->set('length', (int)$file->getSize()); // 文件大小
|
||||
$sysFileRecord->set('content_type', $file->getMime()); // 文件类型(mime)
|
||||
$sysFileRecord->set('md5', $file->md5());// 文件md5
|
||||
$sysFileRecord->set('sha1', $file->sha1()); // 文件sha1
|
||||
$sysFileRecord->set('extension', $file->extension()); // 文件扩展名(extension)
|
||||
$sysFileRecord->set('origin_name', $file->getFilename()); // 文件原始名称
|
||||
$sysFileRecord->set('create_time', date('Y-m-d H:i:s')); // 文件记录创建时间
|
||||
$sysFileRecord->set('create_date', date('Y-m-d')); // 文件记录创建日期
|
||||
// 关联数据相关
|
||||
$sysFileRecord->set('context_id', $contextId); // 来源上下文
|
||||
|
||||
// 返回UploadFile实体类
|
||||
$uploadFile = new UploadFile();
|
||||
$uploadFile->done($file, $sysFileRecord);
|
||||
return $uploadFile;
|
||||
}
|
||||
// public function upload(string $contextId, File $file, SysFileRule $rule): UploadFile
|
||||
// {
|
||||
// $sysFileRecord = new SysFileRecord;
|
||||
// // 存储规则相关
|
||||
// $sysFileRecord->set('rid', $rule->id); // ruleId
|
||||
// $sysFileRecord->set('disk', $rule->disk); // 存储disk
|
||||
// // 文件信息相关
|
||||
// $sysFileRecord->set('path', ''); // 文件存储路径
|
||||
// $sysFileRecord->set('name', ''); // 文件名称
|
||||
// $sysFileRecord->set('length', (int)$file->getSize()); // 文件大小
|
||||
// $sysFileRecord->set('content_type', $file->getMime()); // 文件类型(mime)
|
||||
// $sysFileRecord->set('md5', $file->md5());// 文件md5
|
||||
// $sysFileRecord->set('sha1', $file->sha1()); // 文件sha1
|
||||
// $sysFileRecord->set('extension', $file->extension()); // 文件扩展名(extension)
|
||||
// $sysFileRecord->set('origin_name', $file->getFilename()); // 文件原始名称
|
||||
// $sysFileRecord->set('create_time', date('Y-m-d H:i:s')); // 文件记录创建时间
|
||||
// $sysFileRecord->set('create_date', date('Y-m-d')); // 文件记录创建日期
|
||||
// // 关联数据相关
|
||||
// $sysFileRecord->set('context_id', $contextId); // 来源上下文
|
||||
//
|
||||
// // 返回UploadFile实体类
|
||||
// $uploadFile = new UploadFile();
|
||||
// $uploadFile->done($file, $sysFileRecord);
|
||||
// return $uploadFile;
|
||||
// }
|
||||
}
|
||||
@ -2,6 +2,8 @@
|
||||
|
||||
namespace app\service\file;
|
||||
|
||||
use app\entity\file\UploadResult;
|
||||
use app\entity\SysFileRecord;
|
||||
use app\entity\SysFileRule;
|
||||
use app\entity\SysUserFile;
|
||||
use think\facade\Event;
|
||||
@ -12,6 +14,7 @@ use think\exception\ValidateException;
|
||||
use think\facade\Filesystem;
|
||||
use think\facade\Validate;
|
||||
use think\file\UploadedFile;
|
||||
use think\filesystem\Driver;
|
||||
use think\helper\Str;
|
||||
|
||||
class FilesystemService
|
||||
@ -28,9 +31,9 @@ class FilesystemService
|
||||
* @param int $directory_id 存储的目录位置
|
||||
* @param int $user_id 用户ID
|
||||
* @param array $vars
|
||||
* @return array
|
||||
* @return UploadResult
|
||||
*/
|
||||
public function upload(UploadedFile $file, int $directory_id, int $user_id, array $vars = []): array
|
||||
public function upload(UploadedFile $file, int $directory_id, int $user_id, array $vars = []): UploadResult
|
||||
{
|
||||
$rule_id = 1;
|
||||
if ($directory_id > 0) {
|
||||
@ -42,31 +45,46 @@ class FilesystemService
|
||||
}
|
||||
/*
|
||||
* 文件记录实体
|
||||
* filesystem.model
|
||||
*/
|
||||
$filesystem_model = $this->app->config->get('filesystem.model');
|
||||
if (empty($filesystem_model)) {
|
||||
throw new FileException('File记录模型未定义');
|
||||
}
|
||||
/**
|
||||
* @var SysFileRule $fileRule
|
||||
/*
|
||||
* 文件预览接口(用于安全访问模式)
|
||||
* filesystem.api_url
|
||||
*/
|
||||
$fileRule = SysFileRule::find($rule_id);
|
||||
if (empty($fileRule)) {
|
||||
$filesystem_apiUrl = $this->app->config->get('filesystem.api_url');
|
||||
if (empty($filesystem_apiUrl)) {
|
||||
throw new FileException('请正确配置filesystem.api_url');
|
||||
}
|
||||
if ($filesystem_apiUrl == "#") {
|
||||
$filesystem_apiUrl = Request::domain();
|
||||
} else if (!Validate::url($filesystem_apiUrl)) {
|
||||
throw new FileException('请正确配置filesystem.api_url');
|
||||
}
|
||||
|
||||
/**
|
||||
* @var SysFileRule|\app\model\SysFileRule $rule
|
||||
*/
|
||||
$rule = SysFileRule::find($rule_id);
|
||||
if (empty($rule)) {
|
||||
throw new ValidateException('Rule: 上传规则不存在');
|
||||
}
|
||||
if ($fileRule['is_close']) {
|
||||
if ($rule->is_close) {
|
||||
throw new ValidateException('Rule: 已关闭上传权限');
|
||||
}
|
||||
/*
|
||||
* 根据规则校验上传的文件是否符合要求
|
||||
*/
|
||||
$this->checkFileRule($fileRule, $file);
|
||||
$this->checkFileRule($rule, $file);
|
||||
|
||||
|
||||
$putDisk = $fileRule->disk;
|
||||
$putUrl = $fileRule->url;
|
||||
$putPath = $fileRule->path_rule;
|
||||
$nameRule = $fileRule->name_rule;
|
||||
$putDisk = $rule->disk;
|
||||
$putUrl = $rule->url ? $rule->url : $filesystem_apiUrl;
|
||||
$putPath = $rule->path_rule;
|
||||
$nameRule = $rule->name_rule;
|
||||
|
||||
|
||||
$nameRule = $this->replaceName($nameRule, $file, $vars + ['uid' => $user_id]);
|
||||
@ -77,62 +95,36 @@ class FilesystemService
|
||||
$fileName = pathinfo($savePath, PATHINFO_FILENAME);
|
||||
$filePath = pathinfo($savePath, PATHINFO_DIRNAME);
|
||||
|
||||
// dump(['#1', $putPath, $nameRule]);
|
||||
// dump(['#2', $filePath, $fileName]);
|
||||
|
||||
$filesystemSrv = Filesystem::disk($putDisk);
|
||||
$uploadPath = $filesystemSrv->putFile($filePath, $file, function () use ($fileName) {
|
||||
return $fileName;
|
||||
});
|
||||
$disk = Filesystem::disk('public');
|
||||
$uploadPath = $this->uploadFile($disk, $filePath, $file, $fileName);
|
||||
if ($uploadPath === false) {
|
||||
throw new FileException('上传失败');
|
||||
}
|
||||
$diskConfig = Filesystem::getDiskConfig($putDisk);
|
||||
$url = $diskConfig['url'] ?? '';
|
||||
if ($url && Validate::url($url) === false) {
|
||||
$url = trim($url, '/');
|
||||
$uploadPath = "$url/$uploadPath";
|
||||
$url = "";
|
||||
}
|
||||
$filesystem_apiUrl = $this->app->config->get('filesystem.api_url');
|
||||
/*
|
||||
* URL取值优先级为
|
||||
* #1 取fileRule中的设置 -> #2 取config中的设置 -> #3 取api_url的配置 #4 取当前域名的配置
|
||||
* 注意, fileRule中的permissions配置会把#3,#4做为优先项
|
||||
*/
|
||||
$diskUrl = $putUrl ?: ($url ?: $filesystem_apiUrl ?: Request::domain());
|
||||
$uploadPath = $disk->url($uploadPath);
|
||||
|
||||
$fileUrl = $putUrl . '/' . ltrim($uploadPath, '/');
|
||||
|
||||
$uploadSavePath = pathinfo($uploadPath, PATHINFO_DIRNAME);
|
||||
$fileSaveName = pathinfo($uploadPath, PATHINFO_BASENAME);
|
||||
// dump([$diskUrl, $uploadPath]);
|
||||
// dump(['#4', $uploadSavePath, $fileSaveName]);
|
||||
|
||||
|
||||
// 系统文件上传日志记录
|
||||
$sysFileRecord = $this->app->invokeClass($filesystem_model);
|
||||
$sysFileRecord->save([
|
||||
'rule_id' => $rule->id,
|
||||
'name' => $fileSaveName,
|
||||
'origin_name' => $file->getOriginalName(),
|
||||
'alias_name' => '',
|
||||
'path' => $uploadSavePath,
|
||||
'length' => $file->getSize(),
|
||||
'extension' => $file->getOriginalExtension(),
|
||||
'content_type' => mime_content_type($file->getRealPath()) ?: '',
|
||||
'md5' => $file->md5(),
|
||||
'sha1' => $file->sha1(),
|
||||
'disk' => $putDisk,
|
||||
'uid' => $user_id,
|
||||
'create_user_id' => $user_id,
|
||||
'context_id' => $this->app->request->contextId,
|
||||
'gid' => 0,
|
||||
'create_date' => date('Y-m-d'),
|
||||
'create_time' => date('Y-m-d H:i:s'),
|
||||
'update_time' => date('Y-m-d H:i:s'),
|
||||
'delete_time' => null,
|
||||
'uuid' => guid()
|
||||
]);
|
||||
$sysFileRecordData = $sysFileRecord->toArray();
|
||||
$fileRuleData = $fileRule->toArray();
|
||||
|
||||
if ($user_id > 0) {
|
||||
(new SysUserFile)->save([
|
||||
'user_id' => $user_id,
|
||||
'name' => $file->getOriginalName(),
|
||||
@ -146,32 +138,33 @@ class FilesystemService
|
||||
'disk' => $putDisk,
|
||||
// 存储规则
|
||||
'rule_id' => $rule_id,
|
||||
'uuid' => $sysFileRecord->uuid,
|
||||
'url' => "$diskUrl/{$uploadPath}",
|
||||
'url' => $fileUrl,
|
||||
'is_anonymous' => 0,
|
||||
]);
|
||||
}
|
||||
// 是否需要安全访问
|
||||
if ($fileRule->permissions) {
|
||||
$uploadPath = "i/" . $sysFileRecord->uuid;
|
||||
$diskUrl = $filesystem_apiUrl ?: Request::domain();
|
||||
if ($rule->permissions) {
|
||||
$fileId = hashids(12)->encode($sysFileRecord->id);
|
||||
$uploadPath = "i/" . $fileId;
|
||||
$fileUrl = $putUrl . '/' . ltrim($uploadPath, '/');
|
||||
}
|
||||
$results = [
|
||||
|
||||
/*
|
||||
* 上传结果封装
|
||||
*/
|
||||
$results = new UploadResult([
|
||||
// 文件对外显示URL
|
||||
'url' => "$diskUrl/{$uploadPath}",
|
||||
'url' => $fileUrl,
|
||||
// 文件对外显示存储路径
|
||||
'path' => $uploadPath,
|
||||
// 文件唯一标识符
|
||||
'uuid' => "{$rule_id}@" . $sysFileRecord->uuid,
|
||||
// 文件上传时间戳
|
||||
'time' => time(),
|
||||
];
|
||||
// 触发文件上传事件
|
||||
Event::trigger('upload', ['results' => $results, 'file' => $file, 'rule' => $fileRuleData, 'model' => $sysFileRecordData, 'directory_id' => $directory_id]);
|
||||
// 触发磁盘上传事件
|
||||
Event::trigger("upload.$putDisk", ['results' => $results, 'file' => $file, 'rule' => $fileRuleData, 'model' => $sysFileRecordData, 'directory_id' => $directory_id]);
|
||||
// 触发磁盘某个规则的上传事件
|
||||
Event::trigger("upload.rule_$rule_id", ['results' => $results, 'file' => $file, 'rule' => $fileRuleData, 'model' => $sysFileRecordData, 'directory_id' => $directory_id]);
|
||||
]);
|
||||
|
||||
/*
|
||||
* 触发上传完成事件
|
||||
*/
|
||||
$this->triggerUploaded($results, $putDisk, $file, $rule, $sysFileRecord);
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
@ -241,4 +234,33 @@ class FilesystemService
|
||||
->check(['file' => $file]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 触发上传完成事件
|
||||
* @param UploadResult $results 上传结果
|
||||
* @param string $putDisk 存储磁盘
|
||||
* @param UploadedFile $file 上传的文件
|
||||
* @param SysFileRule $rule 上传规则
|
||||
* @param SysFileRecord $sysFileRecord 文件上传记录
|
||||
* @return void
|
||||
*/
|
||||
private function triggerUploaded(UploadResult $results, string $putDisk, UploadedFile $file, SysFileRule $rule, SysFileRecord $sysFileRecord): void
|
||||
{
|
||||
$eventData = ['results' => $results, 'file' => $file, 'rule' => $rule, 'model' => $sysFileRecord];
|
||||
// 触发文件上传事件
|
||||
Event::trigger('uploaded', $eventData);
|
||||
// 触发磁盘上传事件
|
||||
Event::trigger("uploaded.$putDisk", $eventData);
|
||||
// 触发磁盘某个规则的上传事件
|
||||
if (!empty($rule->id)) {
|
||||
Event::trigger("uploaded.rule_{$rule->id}", $eventData);
|
||||
}
|
||||
}
|
||||
|
||||
private function uploadFile(Driver $driver, string $filePath, UploadedFile $file, string $fileName): bool|string
|
||||
{
|
||||
return $driver->putFile($filePath, $file, function () use ($fileName) {
|
||||
return $fileName;
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -21,5 +21,6 @@ return [
|
||||
],
|
||||
// 更多的磁盘配置信息
|
||||
],
|
||||
'model' => \app\entity\SysFileRecord::class
|
||||
'model' => \app\entity\SysFileRecord::class,
|
||||
'api_url' => "#",
|
||||
];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user