chore: 重写初始提交(清空历史,整理后全量提交)

This commit is contained in:
ywxapp
2026-08-16 16:54:14 +08:00
commit 6c1a106bc1
1808 changed files with 238144 additions and 0 deletions
+180
View File
@@ -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.");
}
}