up.
This commit is contained in:
parent
d79d914ed9
commit
ca6abacb5d
@ -38,4 +38,10 @@ class FileController extends BaseController
|
|||||||
SysFileRecord::destroy($data);
|
SysFileRecord::destroy($data);
|
||||||
return $this->writeSuccess('删除成功');
|
return $this->writeSuccess('删除成功');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function upload()
|
||||||
|
{
|
||||||
|
$file = $this->request->file('file');
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
14
app/entity/SysFileRule.php
Normal file
14
app/entity/SysFileRule.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\entity;
|
||||||
|
|
||||||
|
use think\Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统文件规则实体类
|
||||||
|
* @see \app\model\SysFileRule
|
||||||
|
*/
|
||||||
|
class SysFileRule extends Entity
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
14
app/entity/SysUserFile.php
Normal file
14
app/entity/SysUserFile.php
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\entity;
|
||||||
|
|
||||||
|
use think\Entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统用户文件实体
|
||||||
|
* @see \app\model\SysUserFile
|
||||||
|
*/
|
||||||
|
class SysUserFile extends Entity
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
18
app/entity/UploadFile.php
Normal file
18
app/entity/UploadFile.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace app\model;
|
namespace app\model;
|
||||||
|
|
||||||
use app\adminapi\model\TenantModel;
|
|
||||||
use app\BaseModel;
|
use app\BaseModel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
namespace app\model;
|
namespace app\model;
|
||||||
|
|
||||||
use app\adminapi\model\TenantModel;
|
|
||||||
use app\BaseModel;
|
use app\BaseModel;
|
||||||
use think\model\concern\SoftDelete;
|
use think\model\concern\SoftDelete;
|
||||||
use think\model\relation\HasOne;
|
use think\model\relation\HasOne;
|
||||||
|
|||||||
49
app/service/FileService.php
Normal file
49
app/service/FileService.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\service;
|
||||||
|
|
||||||
|
use app\entity\SysFileRecord;
|
||||||
|
use app\entity\SysFileRule;
|
||||||
|
use app\entity\UploadFile;
|
||||||
|
use think\File;
|
||||||
|
use think\Service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件服务
|
||||||
|
*/
|
||||||
|
class FileService extends Service
|
||||||
|
{
|
||||||
|
public function register(): void
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* 注册到全局容器中
|
||||||
|
*/
|
||||||
|
$this->app->bind('filesystem', $this);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
223
app/service/file/FilesystemUploadService.php
Normal file
223
app/service/file/FilesystemUploadService.php
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace app\service\file;
|
||||||
|
|
||||||
|
use app\BaseService;
|
||||||
|
use app\entity\SysFileRule;
|
||||||
|
use app\entity\SysUserFile;
|
||||||
|
use think\facade\Event;
|
||||||
|
use think\facade\Request;
|
||||||
|
use think\App;
|
||||||
|
use think\exception\FileException;
|
||||||
|
use think\exception\ValidateException;
|
||||||
|
use think\facade\Filesystem;
|
||||||
|
use think\facade\Validate;
|
||||||
|
use think\file\UploadedFile;
|
||||||
|
use think\helper\Str;
|
||||||
|
|
||||||
|
class FilesystemUploadService
|
||||||
|
{
|
||||||
|
public App $app;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param UploadedFile $file 上传的文件
|
||||||
|
* @param int $directory_id 存储的目录位置
|
||||||
|
* @param int $user_id 用户ID
|
||||||
|
* @param array $vars
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function upload(UploadedFile $file, int $directory_id, int $user_id, array $vars = []): array
|
||||||
|
{
|
||||||
|
$rule_id = 1;
|
||||||
|
if ($directory_id > 0) {
|
||||||
|
$directory = SysUserFile::where('is_directory', 1)->find($directory_id);
|
||||||
|
if (empty($directory)) {
|
||||||
|
throw new ValidateException('Dir: 目录不存在');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @var SysFileRule $fileRule
|
||||||
|
*/
|
||||||
|
$fileRule = SysFileRule::find($rule_id);
|
||||||
|
if (empty($fileRule) || $fileRule['is_close']) {
|
||||||
|
throw new ValidateException('Rule: 已关闭上传权限');
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 验证文件信息
|
||||||
|
*/
|
||||||
|
if ($fileRule->rule_file_size_limit_min > 0) {
|
||||||
|
if ($file->getSize() < $fileRule->rule_file_size_limit_min * 1024) {
|
||||||
|
throw new ValidateException('文件限制:文件太小了');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$validateRule = [];
|
||||||
|
if ($fileRule->rule_file_size_limit_max > 0) {
|
||||||
|
$validateRule[] = 'fileSize:' . ($fileRule->rule_file_size_limit_max * 1024);
|
||||||
|
}
|
||||||
|
if ($fileRule->rule_file_ext !== '') {
|
||||||
|
$validateRule[] = "fileExt:$fileRule->rule_file_ext";
|
||||||
|
}
|
||||||
|
if ($fileRule->rule_file_mime !== '') {
|
||||||
|
$validateRule[] = "fileMime:$fileRule->rule_file_mime";
|
||||||
|
}
|
||||||
|
if ($fileRule->rule_image !== '') {
|
||||||
|
$validateRule[] = "image:$fileRule->rule_image";
|
||||||
|
}
|
||||||
|
if ($validateRule) {
|
||||||
|
validate(['file' => implode('|', $validateRule)])
|
||||||
|
->check(['file' => $file]);
|
||||||
|
}
|
||||||
|
$putDisk = $fileRule->disk;
|
||||||
|
$putUrl = $fileRule->url;
|
||||||
|
$putPath = $fileRule->path_rule;
|
||||||
|
$nameRule = $fileRule->name_rule;
|
||||||
|
|
||||||
|
|
||||||
|
$nameRule = $this->replaceName($nameRule, $file, $vars + ['uid' => $user_id]);
|
||||||
|
$putPath = $this->replaceName($putPath, $file, $vars + ['uid' => $user_id]);
|
||||||
|
|
||||||
|
$savePath = ($putPath ? trim($putPath, '/') : '') . '/' . $nameRule;
|
||||||
|
|
||||||
|
$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;
|
||||||
|
});
|
||||||
|
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());
|
||||||
|
$uploadSavePath = pathinfo($uploadPath, PATHINFO_DIRNAME);
|
||||||
|
$fileSaveName = pathinfo($uploadPath, PATHINFO_BASENAME);
|
||||||
|
// dump([$diskUrl, $uploadPath]);
|
||||||
|
// dump(['#4', $uploadSavePath, $fileSaveName]);
|
||||||
|
$filesystem_model = $this->app->config->get('filesystem.model');
|
||||||
|
if (empty($filesystem_model)) $filesystem_model = SysFileRecord::class;
|
||||||
|
|
||||||
|
$sysFileRecord = $this->app->invokeClass($filesystem_model);
|
||||||
|
$sysFileRecord->save([
|
||||||
|
'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(),
|
||||||
|
'is_directory' => 0,
|
||||||
|
'parent_id' => $directory_id,
|
||||||
|
'path' => $uploadPath,
|
||||||
|
'length' => $file->getSize(),
|
||||||
|
'content_type' => $file->getOriginalMime(),
|
||||||
|
'deleted' => 0,
|
||||||
|
// 租户
|
||||||
|
'tenant_id' => $this->app->request->tenantId,
|
||||||
|
// 磁盘
|
||||||
|
'disk' => $putDisk,
|
||||||
|
// 存储规则
|
||||||
|
'rule_id' => $rule_id,
|
||||||
|
'uuid' => $sysFileRecord->uuid,
|
||||||
|
'url' => "$diskUrl/{$uploadPath}",
|
||||||
|
'is_anonymous' => 0,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
// 是否需要安全访问
|
||||||
|
if ($fileRule->permissions) {
|
||||||
|
$uploadPath = "i/" . $sysFileRecord->uuid;
|
||||||
|
$diskUrl = $filesystem_apiUrl ?: Request::domain();
|
||||||
|
}
|
||||||
|
$results = [
|
||||||
|
// 文件对外显示URL
|
||||||
|
'url' => "$diskUrl/{$uploadPath}",
|
||||||
|
// 文件对外显示存储路径
|
||||||
|
'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]);
|
||||||
|
return $results;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private function replaceName(string $pathname, UploadedFile $file, $vars = []): string
|
||||||
|
{
|
||||||
|
$array = [
|
||||||
|
'{Y}' => date('Y'),
|
||||||
|
'{y}' => date('y'),
|
||||||
|
'{m}' => date('m'),
|
||||||
|
'{d}' => date('d'),
|
||||||
|
'{H}' => date('H'),
|
||||||
|
'{i}' => date('i'),
|
||||||
|
'{s}' => date('s'),
|
||||||
|
'{G}' => date('G'),
|
||||||
|
'{Ym}' => date('Ym'),
|
||||||
|
'{Ymd}' => date('Ymd'),
|
||||||
|
'{YmdH}' => date('YmdH'),
|
||||||
|
'{timestamp}' => time(),
|
||||||
|
'{uniqid}' => uniqid(),
|
||||||
|
'{md5}' => md5(microtime() . Str::random()),
|
||||||
|
'{md5-16}' => substr(md5(microtime() . Str::random()), 0, 16),
|
||||||
|
'{str-random-16}' => Str::random(16),
|
||||||
|
'{str-random-10}' => Str::random(10),
|
||||||
|
'{str-random-6}' => Str::random(6),
|
||||||
|
'{fmd5}' => $file->md5(),
|
||||||
|
'{fsha1}' => $file->sha1(),
|
||||||
|
'{fname}' => $file->getOriginalName(),
|
||||||
|
'{uid}' => $vars['uid'] ?? 'UID',
|
||||||
|
];
|
||||||
|
// 系统内部的key不允许被覆盖
|
||||||
|
$useKeys = array_keys($array);
|
||||||
|
foreach ($vars as $key => $value) {
|
||||||
|
if (in_array($key, $useKeys)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
$array["{{$key}}"] = $value;
|
||||||
|
}
|
||||||
|
return str_replace(array_keys($array), array_values($array), $pathname);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -45,8 +45,9 @@ Route::group("adminapi", function () {
|
|||||||
/*
|
/*
|
||||||
* 文件管理
|
* 文件管理
|
||||||
*/
|
*/
|
||||||
Route::get('page', [FileController::class, "page"])->name("system.pageFiles");
|
Route::get('page', [FileController::class, "page"])->name("filesystem.pageFiles");
|
||||||
Route::delete('remove/batch', [FileController::class, "batchRemove"])->name("system.batchRemoveFile");
|
Route::delete('remove/batch', [FileController::class, "batchRemove"])->name("filesystem.batchRemoveFile");
|
||||||
|
Route::post('upload', [FileController::class, "upload"])->name("filesystem.uploadFile");
|
||||||
})->name('文件接口');
|
})->name('文件接口');
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user