init: 项目初始代码

This commit is contained in:
2026-10-14 14:00:29 +08:00
commit cc434cf89f
464 changed files with 66984 additions and 0 deletions

View File

@@ -0,0 +1,204 @@
<?php
namespace storage;
use FceskyUpload\contract\FileInfo;
use FceskyUpload\UploadManager;
use FceskyUpload\drivers\LocalDriver;
class LocalUploader
{
private $config = [];
private $domain = "";
private $_error = "";
public function __construct($conf = [])
{
$this->config = [
'disks' => [
'local' => [
'driver' => LocalDriver::class, //上传类
'save_dir' => app()->getRootPath() . 'public/attachment', //上传保存路径
'file_path' => '/attachment', //上传保存路径
'tmp_dir' => root_path('runtime' . DIRECTORY_SEPARATOR . 'uploadtmp'),//临时目录
'slice_first' => 0, //从第几片开始
],
//继续添加其它仓库
],
'default' => [
'disk' => 'local', //默认磁盘
'extensions' => 'jpg,png,mp4', //后缀
'mimeTypes' => 'image/*,video/*', //类型
'middlewares' => [], //中间件数组
'maxSize' => 1 * 1024 * 1024, //单包最大上传大小 2M
]
];
}
/**文件上传
* @param $data
* @param $file
* @return array
*/
public function uploadFile($data, $file)
{
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
exit; // finish preflight CORS requests here
}
try {
//处理部分数据
$data['size'] = $file->getSize();
$data['name'] = $file->getOriginalName();
$data['ext'] = $file->extension();
//检测文件大小
if (!$this->checkSize($data['size'])) {
$this->_error = "超出文件上传大小限制";
return ['code' => -1, 'data' => []];
}
$config = $this->config;
$uploadManager = new UploadManager($config);
$fileInfo = new FileInfo();
$fileInfo->identifier = $data['hash'];
$fileInfo->filename = $data['name'];
$fileInfo->chunkNumber = $data['chunk'] ?? 0;;
$fileInfo->chunkNumber = intval($fileInfo->chunkNumber ?? 0);
//未设置分片数量 则默认总数为1 当前为0
$fileInfo->totalChunks = $data['chunks'] ?? 1;
$fileInfo->totalChunks = intval($fileInfo->totalChunks ?? 1);
$fileInfo->totalChunks = ($fileInfo->totalChunks > 0) ? $fileInfo->totalChunks : 1;
$fileInfo->totalSize = $data['size'];
//获取后缀
$fileInfo->ext = $data['ext'];
if (!$this->checkFileType($fileInfo->ext)) {
$this->_error = "禁止上传的文件类型";
return ['code' => -1, 'data' => []];
}
$upload = $uploadManager->uploadFile($fileInfo);
//如果文件较小 直接上传完成
if (isset($upload['savepath']) && $upload['code'] == 0) {
$upload = $this->buildFileUrl($upload);
return ['code' => 1, 'data' => $upload, 'msg' => '成功'];
}
$check = $uploadManager->checkFile($fileInfo);
//如果上传完成
if (isset($check['savepath']) && $check['code'] == 0) {
$check = $this->buildFileUrl($check);
return ['code' => 1, 'data' => $check];
} else {
$this->_error = "文件包不完整";
return ['code' => 0, 'data' => $check];
}
} catch (\Exception $e) {
$this->_error = $e->getMessage();
return ['code' => -1, 'data' => $e->getMessage()];
}
}
/**
* 处理文件
* 扩展包存在问题 ,考虑后续更新 尽量不更改扩展包,在这里做文件的处理
*/
public function buildFileUrl($data)
{
if (isset($data['savepath']) && $data['savepath'] != '') {
$conf = $this->config;
//获取除域名外的文件路径
$save_dir = $conf['disks'][$conf['default']['disk']]['save_dir'];
$file_path = str_replace($save_dir, '', $data['savepath']);
//拼接域名
$data['save_path'] = $conf['disks'][$conf['default']['disk']]['file_path'] . $file_path;
$data['file_path'] = $this->domain . $data['save_path'];
//删除多余的信息
unset($data['savepath']);
unset($data['code']);
}
return $data;
}
//检测文件上传大小
public function checkSize($file_size)
{
if ($file_size > $this->config['default']['maxSize']) {
return false;
}
return true;
}
/**检测文件类型
* @param $file_ext
* @return array|bool
*/
public function checkFileType($file_ext)
{ //获取配置信息
$extensions = $this->config['default']['extensions'];
//为空或者为 * 表示不过滤
if ($extensions == "" || $extensions == '*') {
return true;
}
//字符转换成数组
$exts = explode(',', $extensions);
if (in_array($file_ext, $exts)) {
$this->_error = "禁止上传该类型文件";
return ['code' => 0, 'data' => ''];
}
return true;
}
/**
* 检测文件分片情况
*/
public function checkFile($hash,$count){
$filePath = $this->config['disks'][$this->config['default']['disk']]['tmp_dir'] . $hash; //临时分片文件路径
// dump($filePath);
//检查分片是否存在
$chunkExists = [];
for ($index = 0; $index < $count; $index++) {
if (file_exists("{$filePath}_{$index}")) {
array_push($chunkExists, $index);
}
}
//分片有缺失,返回已存在的分片
$res['uploaded'] = $chunkExists;
return $res;
}
/**
* 删除文件
* @param $path
*/
public function deleteFile($path){
$path = app()->getRootPath() . 'public'.$path;
if (file_exists($path)){
@unlink($path);
}
return true;
}
/**
* 返回报错
* @return string
*/
public function getError()
{
return $this->_error;
}
}

View File

@@ -0,0 +1,160 @@
<?php
namespace storage;
use Qiniu\Auth;
use Qiniu\Storage\UploadManager;
use Qiniu\Storage\BucketManager;
class QiniuUploader
{
private $bucket = 'orico-opd';
private $accessKey = 'dOsTum4a5qvhPTBbZRPX0pIOU7PZWRX7htKjztms';
private $secretKey = 'KFxsGbnErkALFfeGdMa8QWTdodJbamMX0iznLe-q';
private $rule = [
'fileSize' => 1024 * 1024 * 5, // 默认最大上传5M
'fileExt' => 'jpeg,jpg,png', // 默认上传文件后缀
'fileMime' => 'image/jpeg,image/png,image/gif' // 默认上传文件mime
];
private $dir = true;
private $originalName = false;
private $pathPrefix = '';
private $fileNamePrefix = 'orico';
static public $domain = 'http://opdfile.f2b211.com/';
public function __construct($conf = [])
{
if (!empty($conf['bucket'])) {
$this->bucket = $conf['bucket'];
}
if (!empty($conf['accessKey'])) {
$this->accessKey = $conf['accessKey'];
}
if (!empty($conf['secretKey'])) {
$this->secretKey = $conf['secretKey'];
}
if (!empty($conf['pathPrefix'])) {
$this->pathPrefix = trim($conf['pathPrefix'], '/');
}
}
/**
* 生成随机字符串
*/
private function random($length, $type = "string", $convert = "0")
{
$conf = [
'number' => '0123456789',
'string' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',
'all' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789='
];
$string = $conf[$type];
if (!$string) {
$string = $conf['string'];
}
$strlen = strlen($string) - 1;
$char = '';
for ($i = 0; $i < $length; $i++) {
$char .= $string[mt_rand(0, $strlen)];
}
if ($convert > 0) {
$res = strtoupper($char);
} elseif ($convert == 0) {
$res = $char;
} elseif ($convert < 0) {
$res = strtolower($char);
}
return $res;
}
/**
* 组装文件名
*/
private function buildFileName()
{
return $this->fileNamePrefix . time() . substr(time(), -5) . substr(microtime(), 2, 3) . $this->random(8);
}
/**
* 上传验证规则
*/
public function validate($rule)
{
$this->rule = $rule;
}
/**
* 上传文件到七牛云
*/
public function uploadFile($name)
{
// 构建鉴权对象
$auth = new Auth($this->accessKey, $this->secretKey);
// 生成上传 Token
$token = $auth->uploadToken($this->bucket);
// 初始化 UploadManager 对象并进行文件的上传。
$uploadMgr = new UploadManager();
$file = request()->file($name);
$aspectRatio = [];
if (!empty($this->rule['aspectRatio'])) {
$aspectRatio = $this->rule['aspectRatio'];
unset($this->rule['aspectRatio']);
}
$validate = validate([$name => $this->rule]);
if (!$validate->check([$name => $file])) {
throw new \Exception($validate->getError());
}
$fileName = $file->getOriginalName(); // 文件原名
if (!$this->originalName) {
$fileName = $this->buildFileName() . '.' . $file->extension();
if (!$this->dir && !empty($this->pathPrefix)) {
$fileName = $this->pathPrefix . '/' . $fileName;
}
}
if ($this->dir) {
$fileName = date('Y') . '/' . date('m') . '/' . date('d') . '/' . $fileName;
if (!empty($this->pathPrefix)) {
$fileName = $this->pathPrefix . '/' . $fileName;
}
}
$filePath = $file->getPathname(); // 临时路径
if (!empty($aspectRatio)) { // 验证图片宽高
list($width, $height, $type, $attr) = getimagesize($file);
if ($width != $aspectRatio['width'] || $height != $aspectRatio['height']) {
throw new \Exception('图片宽高不符合');
}
}
$fileType = $file->getOriginalMime();
list($ret, $err) = $uploadMgr->putFile($token, $fileName, $filePath, null, $fileType, false);
if ($err !== null) {
throw new \Exception($err);
} else {
return ['hash' => $ret['hash'], 'filename' => $ret['key'], 'remote_url' => self::$domain . $ret['key']];
}
}
/**
* 上传文件到七牛云
*/
public function deleteFile($name)
{
// 构建鉴权对象
$auth = new Auth($this->accessKey, $this->secretKey);
// 初始化 BucketManager 对象并进行文件的删除。
$bucketManager = new BucketManager($auth);
$ret = $bucketManager->delete($this->bucket, $name);
return $ret;
}
}