This commit is contained in:
Your Name
2026-07-22 10:18:59 +08:00
parent 2530ddada6
commit 0fb03d0bca
618 changed files with 19445 additions and 3 deletions
+132
View File
@@ -0,0 +1,132 @@
<?php
namespace app\controller\api;
use app\model\UploadFile;
use app\service\PermissionService;
use think\exception\HttpResponseException;
class Upload extends BaseApi
{
public function upload()
{
$user = $this->authUser();
$file = $this->request->file('file');
if (!$file) {
return $this->error('请选择文件');
}
$mime = $file->getMime() ?: mime_content_type($file->getPathname());
$fileType = $this->detectFileType($mime);
if (!PermissionService::canUpload($user, $fileType)) {
return $this->error('您没有权限上传此类型文件或功能未开启', 403);
}
$maxSize = PermissionService::getMaxUploadSizeMb($user) * 1024 * 1024;
if ($file->getSize() > $maxSize) {
return $this->error('文件大小超出限制');
}
if (!$this->isAllowedMime($mime, $fileType)) {
return $this->error('不支持的文件类型');
}
$originalName = $file->getOriginalName();
$fileSize = $file->getSize();
$uploadPath = config('upload.path');
if (!is_dir($uploadPath)) {
mkdir($uploadPath, 0755, true);
}
$ext = $file->extension() ?: 'bin';
$subdir = date('Y/m/d');
$storedBase = uniqid() . '.' . $ext;
$storedName = $subdir . '/' . $storedBase;
$fullDir = $uploadPath . '/' . $subdir;
if (!is_dir($fullDir)) {
mkdir($fullDir, 0755, true);
}
$file->move($fullDir, $storedBase);
$record = UploadFile::create([
'user_id' => $user['id'],
'original_name' => $originalName,
'stored_name' => $storedBase,
'file_path' => $storedName,
'mime_type' => $mime,
'file_size' => $fileSize,
'file_type' => $fileType,
]);
return $this->success([
'id' => $record->id,
'url' => '/api/uploads/' . urlencode($storedBase),
'name' => $originalName,
'type' => $fileType,
'mime' => $mime,
'size' => $fileSize,
]);
}
public function serve($filename)
{
$filename = basename($filename);
$upload = UploadFile::where('stored_name', $filename)
->whereOr('file_path', 'like', '%/' . $filename)
->find();
if (!$upload) {
throw new HttpResponseException(json([
'code' => 1,
'message' => '文件不存在',
'data' => null,
], 404));
}
$path = config('upload.path') . '/' . $upload->file_path;
if (!is_file($path)) {
throw new HttpResponseException(json([
'code' => 1,
'message' => '文件不存在',
'data' => null,
], 404));
}
return download($path, $upload->original_name, true)
->mimeType($upload->mime_type);
}
private function detectFileType(string $mime): string
{
if (str_starts_with($mime, 'image/')) {
return 'image';
}
if (str_starts_with($mime, 'video/')) {
return 'video';
}
if (str_starts_with($mime, 'audio/')) {
return 'audio';
}
if (in_array($mime, config('upload.allowed_documents'), true)) {
return 'document';
}
return 'other';
}
private function isAllowedMime(string $mime, string $fileType): bool
{
$config = config('upload');
return match ($fileType) {
'image' => in_array($mime, $config['allowed_images'], true),
'video' => in_array($mime, $config['allowed_videos'], true),
'audio' => in_array($mime, $config['allowed_audios'], true),
'document' => in_array($mime, $config['allowed_documents'], true),
default => false,
};
}
}