chore: 重写初始提交(清空历史,整理后全量提交)
This commit is contained in:
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
// +----------------------------------------------------------------------
|
||||
// | YwxApp [ WE CAN DO IT JUST THINK ]
|
||||
// +----------------------------------------------------------------------
|
||||
// | Copyright (c) 2026-2036 http://ywxapp.cn All rights reserved.
|
||||
// +----------------------------------------------------------------------
|
||||
// | Author: ywxapp<admin@ywxapp.cn>
|
||||
// +----------------------------------------------------------------------
|
||||
namespace ywxapp\service;
|
||||
|
||||
use think\Exception;
|
||||
use think\facade\Config;
|
||||
use think\file\UploadedFile;
|
||||
use ywxapp\utils\storage\StorageInterface;
|
||||
|
||||
/**
|
||||
* FileStorageService 类
|
||||
*
|
||||
* @author ywxapp <admin@ywxapp.cn>
|
||||
*/
|
||||
class FileStorageService
|
||||
{
|
||||
// 驱动常量
|
||||
const DRIVER_LOCAL = 'local';
|
||||
const DRIVER_ALIOSS = 'alioss';
|
||||
const DRIVER_QCOS = 'qcos';
|
||||
|
||||
protected $config;
|
||||
protected $storage;
|
||||
|
||||
/**
|
||||
* 构造函数,读取配置并初始化驱动
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
// 读取配置文件
|
||||
$this->config = Config::get('filesystem', []);
|
||||
// 获取当前配置的驱动名称
|
||||
$driverName = $this->config['default'] ?? self::DRIVER_LOCAL;
|
||||
// 实例化对应的驱动
|
||||
$this->initDriver($driverName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化存储驱动
|
||||
*/
|
||||
protected function initDriver(string $driverName): void
|
||||
{
|
||||
$drivers = $this->config['disks'] ?? [];
|
||||
if (! isset($drivers[$driverName])) {
|
||||
throw new Exception("存储驱动配置不存在: {$driverName}");
|
||||
}
|
||||
$config = $drivers[$driverName];
|
||||
$class = $config['class'];
|
||||
if (! class_exists($class)) {
|
||||
throw new Exception("存储驱动类不存在: {$class}");
|
||||
}
|
||||
$this->storage = new $class($config);
|
||||
if (! $this->storage instanceof StorageInterface) {
|
||||
throw new Exception("存储驱动必须实现 StorageInterface 接口");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 上传文件(对外调用的方法)
|
||||
*/
|
||||
public function upload(UploadedFile $file, string $path = '', array $options = []): array
|
||||
{
|
||||
|
||||
// 1. 基础验证(例如文件大小、类型)
|
||||
$this->validateFile($file, $options);
|
||||
// 2. 如果未指定路径,生成默认路径
|
||||
if (empty($path)) {
|
||||
$path = $this->generatePath($file);
|
||||
}
|
||||
// throw new \think\Exception(json_encode( [
|
||||
// $file->getoriginalName(), //获取文件原始名称带后缀
|
||||
// $file->getSize(), //获取文件大小
|
||||
// $file->extension(), //获取文件后缀
|
||||
// ])
|
||||
// , 403);
|
||||
// 3. 调用具体驱动的上传方法
|
||||
|
||||
$data = [
|
||||
'module' => $options['module'] ?? 'index', // 模块标识
|
||||
'original' => $file->getoriginalName(),
|
||||
'size' => $file->getSize(),
|
||||
'ext' => $file->extension(),
|
||||
'mime' => $file->getOriginalMime(),
|
||||
'mime' => $file->getMime(),
|
||||
'storage' => $this->config['default'] ?? self::DRIVER_LOCAL,
|
||||
'is_image' => (int) str_starts_with($file->getMime(), 'image/'),
|
||||
'upload_ip' => request()->ip(),
|
||||
];
|
||||
|
||||
// 如果是图片且能获取到尺寸
|
||||
if ($data['is_image'] && function_exists('getimagesize')) {
|
||||
// 注意:如果是云存储,这里可能需要从临时文件获取尺寸
|
||||
$tempPath = $file->getRealPath();
|
||||
if (file_exists($tempPath)) {
|
||||
$imgInfo = getimagesize($tempPath);
|
||||
$data['width'] = $imgInfo[0] ?? 0;
|
||||
$data['height'] = $imgInfo[1] ?? 0;
|
||||
}
|
||||
}
|
||||
|
||||
list($name, $path, $url) = $this->storage->upload($file, $path, $options);
|
||||
$data['name'] = $name;
|
||||
$data['path'] = $path;
|
||||
$data['url'] = $url;
|
||||
|
||||
return $data;
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除文件
|
||||
*/
|
||||
public function delete(string $path): bool
|
||||
{
|
||||
return $this->storage->delete($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取URL
|
||||
*/
|
||||
public function getUrl(string $path): string
|
||||
{
|
||||
return $this->storage->getUrl($path);
|
||||
}
|
||||
|
||||
/**
|
||||
* 基础文件验证
|
||||
*/
|
||||
protected function validateFile(UploadedFile $file, array $options): void
|
||||
{
|
||||
|
||||
// 使用验证器验证上传的文件
|
||||
validate(
|
||||
[
|
||||
'file' => [
|
||||
// 限制文件大小(单位b),这里限制为4M
|
||||
'fileSize' => 4 * 1024 * 1024,
|
||||
// 限制文件后缀,多个后缀以英文逗号分割
|
||||
'fileExt' => 'gif,jpg,png',
|
||||
// fileSize 上传文件的最大字节;
|
||||
// fileExt 文件后缀,多个用逗号分割或者数组;
|
||||
// fileMime 文件MIME类型,多个用逗号分割或者数组;
|
||||
// image 验证图像文件的尺寸和类型,
|
||||
],
|
||||
],
|
||||
[
|
||||
'file.fileSize' => '文件太大',
|
||||
'file.fileExt' => '不支持的文件后缀',
|
||||
]
|
||||
)->check(['file' => $file]);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成唯一文件路径
|
||||
*/
|
||||
protected function generatePath(UploadedFile $file): string
|
||||
{
|
||||
$ext = $file->getClientOriginalExtension();
|
||||
$date = date('Y/m/d');
|
||||
$filename = date('His') . '_' . uniqid() . ".{$ext}";
|
||||
return "{$date}/{$filename}";
|
||||
}
|
||||
|
||||
/**
|
||||
* 魔术方法,允许直接调用驱动的其他特有方法
|
||||
*/
|
||||
public function __call($method, $parameters)
|
||||
{
|
||||
if (method_exists($this->storage, $method)) {
|
||||
return call_user_func_array([$this->storage, $method], $parameters);
|
||||
}
|
||||
throw new \BadMethodCallException("Method {$method} does not exist.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user