238 lines
6.6 KiB
PHP
238 lines
6.6 KiB
PHP
<?php
|
|
|
|
namespace app\common\service;
|
|
|
|
use app\common\validate\UploadedFilesValidate;
|
|
use app\common\traits\crud\CrudServiceTrait;
|
|
use app\common\model\UploadedFiles;
|
|
use support\Request;
|
|
use support\exception\BusinessException;
|
|
|
|
class UploadedFilesService
|
|
{
|
|
|
|
use CrudServiceTrait;
|
|
|
|
/**
|
|
* 指定当前要操作的模型
|
|
*/
|
|
protected string $modelClass = UploadedFiles::class;
|
|
|
|
/**
|
|
* 文件上传分区配置
|
|
*/
|
|
protected array $uploadPartitions = [
|
|
'image' => [
|
|
'path' => 'images',
|
|
'max_size' => 5 * 1024 * 1024, // 5MB
|
|
'allowed_types' => ['image/jpeg', 'image/png', 'image/gif', 'image/webp'],
|
|
'extensions' => ['jpg', 'jpeg', 'png', 'gif', 'webp']
|
|
],
|
|
'document' => [
|
|
'path' => 'documents',
|
|
'max_size' => 10 * 1024 * 1024, // 10MB
|
|
'allowed_types' => ['application/pdf', 'application/msword', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'],
|
|
'extensions' => ['pdf', 'doc', 'docx']
|
|
],
|
|
'audio' => [
|
|
'path' => 'audios',
|
|
'max_size' => 20 * 1024 * 1024, // 20MB
|
|
'allowed_types' => ['audio/mp3', 'audio/wav', 'audio/ogg'],
|
|
'extensions' => ['mp3', 'wav', 'ogg']
|
|
],
|
|
'other' => [
|
|
'path' => 'others',
|
|
'max_size' => 5 * 1024 * 1024, // 5MB
|
|
'allowed_types' => [],
|
|
'extensions' => []
|
|
]
|
|
];
|
|
|
|
/**
|
|
* 记录文件信息到数据库
|
|
*
|
|
* @param array $fileInfo 文件信息
|
|
* @param Request|null $request 请求对象(可选)
|
|
* @param string $partition 分区名称
|
|
* @param string $category 文件分类
|
|
* @return array
|
|
* @throws BusinessException
|
|
*/
|
|
public function recordFileInfo(array $fileInfo, ?Request $request = null, string $partition = 'other', string $category = 'general'): array
|
|
{
|
|
|
|
// 验证必需的文件信息
|
|
$requiredFields = ['file_name', 'file_path', 'file_size', 'file_type'];
|
|
foreach ($requiredFields as $field) {
|
|
if (!isset($fileInfo[$field])) {
|
|
throw new BusinessException("缺少必需的文件信息字段: {$field}");
|
|
}
|
|
}
|
|
|
|
// 获取文件扩展名
|
|
$fileExtension = pathinfo($fileInfo['file_name'], PATHINFO_EXTENSION);
|
|
|
|
// 记录到数据库
|
|
$uploadIp = $request ? $request->getRealIp() : '0.0.0.0';
|
|
$userAgent = $request ? $request->header('User-Agent', '') : '';
|
|
|
|
$fileData = [
|
|
'file_name' => $fileInfo['file_name'],
|
|
'file_path' => $fileInfo['file_path'],
|
|
'file_size' => $fileInfo['file_size'],
|
|
'file_type' => $fileInfo['file_type'],
|
|
'category' => $category,
|
|
'original_name' => $fileInfo['original_name'] ?? '',
|
|
'extension' => $fileExtension,
|
|
'partition' => $partition,
|
|
'upload_ip' => $uploadIp,
|
|
'user_agent' => $userAgent,
|
|
];
|
|
|
|
$uploadedFile = $this->logicCreate($fileData);
|
|
|
|
return [
|
|
'id' => $uploadedFile->id,
|
|
'file_name' => $fileInfo['file_name'],
|
|
'file_path' => $fileInfo['file_path'],
|
|
'file_url' => getenv('MAIN_DOMAIN') . $fileInfo['file_path'],
|
|
'file_size' => $fileInfo['file_size'],
|
|
'file_type' => $fileInfo['file_type'],
|
|
'category' => $category,
|
|
'partition' => $partition,
|
|
'original_name' => $fileInfo['original_name'] ?? '',
|
|
'extension' => $fileExtension,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取文件信息
|
|
*
|
|
* @param int $fileId
|
|
* @return array|null
|
|
*/
|
|
public function getFileInfo(int $fileId): ?array
|
|
{
|
|
$file = $this->logicShow(['where' => ['id' => $fileId]]);
|
|
|
|
if (!$file) {
|
|
return null;
|
|
}
|
|
|
|
return [
|
|
'id' => $file->id,
|
|
'file_name' => $file->file_name,
|
|
'file_path' => $file->file_path,
|
|
'file_url' => getenv('MAIN_DOMAIN') . $file->file_path,
|
|
'file_size' => $file->file_size,
|
|
'file_type' => $file->file_type,
|
|
'category' => $file->category,
|
|
'partition' => $file->partition ?? 'other',
|
|
'original_name' => $file->original_name ?? '',
|
|
'extension' => $file->extension ?? '',
|
|
'created_at' => $file->created_at,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* 获取文件
|
|
*
|
|
* @param string $path
|
|
* @return bool|\Illuminate\Database\Eloquent\Model
|
|
*/
|
|
public function getFile(array $where)
|
|
{
|
|
$config['model'] = $this->modelClass;
|
|
$config['where'] = $where;
|
|
$file = $this->logicShow($config);
|
|
|
|
if (!$file) {
|
|
return false;
|
|
}
|
|
|
|
return $file;
|
|
}
|
|
/**
|
|
* 获取文件
|
|
*
|
|
* @param string $path
|
|
* @return bool|\Illuminate\Database\Eloquent\Model
|
|
*/
|
|
public function findFile(array $where)
|
|
{
|
|
$file = UploadedFiles::where(['file_path' => $where['file_path']]);
|
|
|
|
if (!$file) {
|
|
return false;
|
|
}
|
|
|
|
return $file;
|
|
}
|
|
|
|
/**
|
|
* 删除文件
|
|
*
|
|
* @param int $fileId
|
|
* @return bool
|
|
*/
|
|
public function deleteFile(int $fileId): bool
|
|
{
|
|
$config['model'] = $this->modelClass;
|
|
$config['where'] = ['id' => $fileId];
|
|
$file = $this->logicShow($config);
|
|
|
|
if (!$file) {
|
|
return false;
|
|
}
|
|
|
|
// 删除数据库记录
|
|
$config =[
|
|
'model' => $this->modelClass,
|
|
'where' => ['id' => $fileId],
|
|
];
|
|
return $this->logicDeleteBy($config);
|
|
}
|
|
|
|
/**
|
|
* 获取分区配置
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getPartitionConfig(): array
|
|
{
|
|
return $this->uploadPartitions;
|
|
}
|
|
|
|
/**
|
|
* 生成文件名
|
|
*
|
|
* @param $file
|
|
* @return string
|
|
*/
|
|
protected function generateFileName($file): string
|
|
{
|
|
$extension = $file->getUploadExtension();
|
|
$timestamp = time();
|
|
$random = substr(md5(uniqid()), 0, 8);
|
|
|
|
return $timestamp . '_' . $random . '.' . $extension;
|
|
}
|
|
|
|
/**
|
|
* 格式化文件大小
|
|
*
|
|
* @param int $bytes
|
|
* @return string
|
|
*/
|
|
protected function formatFileSize(int $bytes): string
|
|
{
|
|
$units = ['B', 'KB', 'MB', 'GB'];
|
|
$bytes = max($bytes, 0);
|
|
$pow = floor(($bytes ? log($bytes) : 0) / log(1024));
|
|
$pow = min($pow, count($units) - 1);
|
|
|
|
$bytes /= pow(1024, $pow);
|
|
|
|
return round($bytes, 2) . ' ' . $units[$pow];
|
|
}
|
|
} |