初始化

This commit is contained in:
liut
2021-10-12 11:06:24 +08:00
commit ff0b4d5b12
1270 changed files with 405680 additions and 0 deletions
@@ -0,0 +1,185 @@
<?php
namespace app\common\model\driver;
use OSS\Core\OssException;
use OSS\OssClient;
use think\Exception;
use think\facade\Cache;
class AliyunOss extends PolicyStore
{
public function uploadSimple(){
// 临时文件地址
$temp_file = $this->path['temp_path'] . $this->path['filename'];
// 保存临时文件
$file_info = $this->info['file']['data']->move($this->path['temp_path'],$this->path['filename']);
if(!$file_info){
throw new Exception($this->info['file']['data']->getError());
}
$accessKeyId = $this->policy['config']['access_key'];
$accessKeySecret = $this->policy['config']['access_secret'];
$endpoint = $this->policy['config']['endpoint'];
$bucket = $this->policy['config']['bucket'];
$policy_save_dir = ltrim($this->policy['config']['save_dir'],'/');
$object = getDiyDirSeparator('/',$policy_save_dir. $this->path['file'].$this->path['filename']);
try{
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint);
$ossClient->uploadFile($bucket,$object,$temp_file);
// 删除临时文件
@unlink($temp_file);
// 返回文件存储地址
return '/'. $object;
} catch(OssException $e) {
throw new Exception('FAILED'.$e->getMessage());
}
}
public function uploadPart()
{
// 临时文件地址
$temp_file = $this->path['temp_path'] . $this->path['filename'];
// 保存临时文件
$file_info = $this->info['file']['data']->move($this->path['temp_path'],$this->path['filename']);
if(!$file_info){
throw new Exception($this->info['file']['data']->getError());
}
$accessKeyId = $this->policy['config']['access_key'];
$accessKeySecret = $this->policy['config']['access_secret'];
$endpoint = $this->policy['config']['endpoint'];
$bucket = $this->policy['config']['bucket'];
$policy_save_dir = ltrim($this->policy['config']['save_dir'],'/');
// 缓存分片上传地址
$chunks_object_keys = 'aliyun_oss_chunks_'.$this->info['chunk']['key'];
$multi_upload_object = Cache::get($chunks_object_keys);
try {
$client = new OssClient($accessKeyId,$accessKeySecret,$endpoint);
// 缓存防止重复文件地址
if(empty($multi_upload_object)){
$upload_object_path = getDiyDirSeparator('/',$policy_save_dir. $this->path['file'].$this->path['filename']);
$uploadId = $client->initiateMultipartUpload($bucket,$upload_object_path);
$multi_upload_object = [
'object' => $upload_object_path,
'upload_id' => $uploadId
];
Cache::set($chunks_object_keys,$multi_upload_object);
}
// 分片上传配置
$options = [
// 上传文件地址
OssClient::OSS_FILE_UPLOAD => $temp_file,
// 分片号
OssClient::OSS_PART_NUM => $this->info['chunk']['chunk'] + 1,
];
$client->uploadPart($bucket, $multi_upload_object['object'], $multi_upload_object['upload_id'], $options);
// 组合文件
if(($this->info['chunk']['chunk'] + 1) == $this->info['chunk']['chunks']){
// 获取所有分片信息
$listPartsInfo = $client->listParts($bucket, $multi_upload_object['object'], $multi_upload_object['upload_id']);
$uploadParts = [];
foreach ($listPartsInfo->getListPart() as $partInfo) {
$uploadParts[] = [
'PartNumber' => $partInfo->getPartNumber(),
'ETag' => $partInfo->getETag()
];
}
// 合并分片
$client->completeMultipartUpload($bucket, $multi_upload_object['object'], $multi_upload_object['upload_id'], $uploadParts);
// 删除分片缓存信息
Cache::rm($chunks_object_keys);
// 删除临时文件
@unlink($temp_file);
// 返回结果
return '/' . $multi_upload_object['object'];
}
// 删除临时文件
@unlink($temp_file);
return 'chunk_file';
}catch (OssException $e){
throw new Exception('FAILED'.$e->getMessage());
}
}
public function download($stores, $speed, $policy)
{
$accessKeyId = $policy['config']['access_key'];
$accessKeySecret = $policy['config']['access_secret'];
$endpoint = $policy['config']['endpoint'];
$bucket = $policy['config']['bucket'];
$object = ltrim($stores['file_name'],'/');
// 限速下载
if($speed !== ""){
// 下载速度
$down_speed = round(intval($speed) * 8192);
// 最小限速100kb/s
if($down_speed < 819200){
$down_speed = 819200;
}
$options = [
OssClient::OSS_TRAFFIC_LIMIT => $down_speed
];
}
try {
$ossClient = new OssClient($accessKeyId,$accessKeySecret,$endpoint);
$options['response-content-disposition'] = 'attachment; filename='.$stores['origin_name'];
// 120s有效期
$timeout = 120;
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout, "GET", $options);
// 跳转下载地址
return redirect($signedUrl);
}catch (OssException $e){
throw new Exception($e->getMessage());
}
}
}
+125
View File
@@ -0,0 +1,125 @@
<?php
namespace app\common\model\driver;
use think\Exception;
use think\facade\Cache;
class Local extends PolicyStore
{
public function uploadSimple()
{
// 保存文件
$file_info = $this->info['file']['data']->move($this->path['path'],$this->path['name']);
if(!$file_info){
throw new Exception($this->info['file']['data']->getError());
}
$policy_save_dir = $this->policy['config']['save_dir'];
return getDiyDirSeparator('/',$policy_save_dir. $this->path['file'].$this->path['filename']);
}
public function uploadPart()
{
// 分片数据存储名称
$chunks_saveKey = 'chunks_'.$this->info['uid'].'_'.$this->info['chunk']['key'];
// 文件名称
$temp_filename = 'chunks_'.md5($this->info['chunk']['key']).'_'.$this->getRandomKey(4) . '_part_'.$this->info['chunk']['chunk'].'.chunk';
// 临时文件地址
$temp_file = $this->path['temp_path'] . $temp_filename;
// 保存临时文件
$file_info = $this->info['file']['data']->move($this->path['temp_path'],$temp_filename);
if(!$file_info){
throw new Exception('分片创建错误:'.$this->info['file']['data']->getError());
}
// 分片存储列表
$chunk_list = Cache::get($chunks_saveKey) ?? [];
// 加入分片文件
$chunk_list[] = $temp_file;
// 保存分片临时存储列表
Cache::set($chunks_saveKey,$chunk_list);
// 分片上传成功
if($this->info['chunk']['chunk'] == ($this->info['chunk']['chunks'] - 1)){
$save_file = $this->path['path'] . $this->path['filename'];
// 融合文件路径
$fileObj = fopen($save_file,"a+");
// 融合文件
foreach ($chunk_list as $value) {
$chunkObj = fopen($value, "rb");
if(!($fileObj && $chunkObj)){
throw new Exception('分片融合文件创建失败');
}
$content = fread($chunkObj, (2 * 1024 * 1024));
fwrite($fileObj, $content, (2 * 1024 * 1024));
unset($content);
fclose($chunkObj);
// 删除分片文件
unlink($value);
}
// 清空分片临时存储列表
Cache::rm($chunks_saveKey);
$policy_save_dir = $this->policy['config']['save_dir'];
return getDiyDirSeparator('/',$policy_save_dir. $this->path['file'] . $this->path['filename']);
}
return 'chunk_file';
}
protected function getRandomKey($length = 16){
$charTable = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$result = "";
for ( $i = 0; $i < $length; $i++ ){
$result .= $charTable[ mt_rand(0, strlen($charTable) - 1) ];
}
return $result;
}
public function download($stores,$speed,$policy)
{
//存储文件地址
$_file = getSafeDirSeparator(env('root_path').'public'.$stores['file_name']);
// 文件不存在
if(!is_file($_file)){
throw new Exception('文件不存在,可能已被删除');
}
$_file_path = $stores['file_name'];
$_file_limit_size = round(intval($speed) * 1024);
// 启用 nginx X-Accel 下载
header('Content-Type: application/octet-stream');
$encoded_fname = rawurlencode($stores['origin_name']);
header('Content-Disposition: attachment;filename="'.$encoded_fname.'";filename*=utf-8'."''".$encoded_fname);
header('X-Accel-Redirect: '. $_file_path);
header('X-Accel-Buffering: yes');
// 不限速下载
if($speed !== ""){
header('X-Accel-Limit-Rate:'.$_file_limit_size);
}
}
}
@@ -0,0 +1,46 @@
<?php
namespace app\common\model\driver;
abstract class PolicyStore
{
protected $info;
protected $policy;
protected $path;
public function __construct($info,$policy,$path)
{
$this->info = $info;
$this->policy = $policy;
$this->path = $path;
}
public function upload()
{
if(!empty($this->info['chunk']['chunks'])){
return $this->uploadPart();
}else{
return $this->uploadSimple();
}
}
public function uploadSimple()
{
return 0;
}
public function uploadPart()
{
return 0;
}
public function download($stores,$speed,$policy)
{
return 0;
}
}
@@ -0,0 +1,210 @@
<?php
namespace app\common\model\driver;
use Qcloud\Cos\Client;
use Qcloud\Cos\Exception\ServiceResponseException;
use think\Exception;
use think\facade\Cache;
class TxyunOss extends PolicyStore
{
public function uploadSimple(){
$secretId = $this->policy['config']['secret_id'];
$secretKey = $this->policy['config']['secret_key'];
$region = $this->policy['config']['region'];
$bucket = $this->policy['config']['bucket'];
// 文件路径
$file_path = $this->info['file']['data']->getInfo('tmp_name');
$file = fopen($file_path, 'rb');
// 存储路径
$policy_save_dir = ltrim($this->policy['config']['save_dir'],'/');
$object = getDiyDirSeparator('/',$policy_save_dir. $this->path['file'].$this->path['filename']);
try {
// COS对象
$client = new Client([
'region' => $region,
'schema' => 'http',
'credentials' => [
'secretId' => $secretId,
'secretKey' => $secretKey
]
]);
if ($file) {
// 上传文件
$client->putObject([
'Bucket' => $bucket,
'Key' => $object,
'Body' => $file
]);
// 返回文件存储地址
return '/'. $object;
}else{
throw new Exception('上传文件路径错误');
}
}catch (ServiceResponseException $e){
throw new Exception($e->getMessage());
}catch (\Exception $e) {
throw new Exception($e->getMessage());
}
}
public function uploadPart()
{
// 配置信息
$secretId = $this->policy['config']['secret_id'];
$secretKey = $this->policy['config']['secret_key'];
$region = $this->policy['config']['region'];
$bucket = $this->policy['config']['bucket'];
// 分片数据存储名称
$chunks_saveKey = 'txyunoss_chunks_'.$this->info['uid'].'_'.$this->info['chunk']['key'];
// 文件名称
$temp_filename = 'chunks_'.md5($this->info['chunk']['key']).'_'.$this->getRandomKey(4) . '_part_'.$this->info['chunk']['chunk'].'.chunk';
// 临时文件地址
$temp_file = $this->path['temp_path'] . $temp_filename;
// 保存临时文件
$file_info = $this->info['file']['data']->move($this->path['temp_path'],$temp_filename);
if(!$file_info){
throw new Exception('分片创建错误:'.$this->info['file']['data']->getError());
}
// 分片存储列表
$chunk_list = Cache::get($chunks_saveKey) ?? [];
// 加入分片文件
$chunk_list[] = $temp_file;
// 保存分片临时存储列表
Cache::set($chunks_saveKey,$chunk_list);
// 分片上传成功
if($this->info['chunk']['chunk'] == ($this->info['chunk']['chunks'] - 1)){
// COS对象
$client = new Client([
'region' => $region,
'schema' => 'http',
'credentials' => [
'secretId' => $secretId,
'secretKey' => $secretKey
]
]);
$save_file = $this->path['temp_path'] . 'cos_cob_'.substr(md5($this->info['chunk']['key']),0,8).'_t_'.time().'.bak';
// 融合文件路径
$fileObj = fopen($save_file,"a+");
// 融合文件
foreach ($chunk_list as $value) {
$chunkObj = fopen($value, "rb");
if(!($fileObj && $chunkObj)){
throw new Exception('分片融合文件创建失败');
}
$content = fread($chunkObj, (2 * 1024 * 1024));
fwrite($fileObj, $content, (2 * 1024 * 1024));
unset($content);
fclose($chunkObj);
// 删除分片文件
unlink($value);
}
// 清空分片临时存储列表
Cache::rm($chunks_saveKey);
try {
$policy_save_dir = $this->policy['config']['save_dir'];
$upload_object_path = getDiyDirSeparator('/',$policy_save_dir. $this->path['file'].$this->path['filename']);
if ($fileObj) {
// 上传文件
$client->Upload($bucket,$upload_object_path,$fileObj);
// 删除临时组合文件
@unlink($save_file);
return $upload_object_path;
}else{
throw new Exception('上传文件路径错误');
}
}catch (ServiceResponseException $e){
throw new Exception($e->getMessage());
}catch (\Exception $e) {
throw new Exception($e->getMessage());
}
}
return 'chunk_file';
}
protected function getRandomKey($length = 16){
$charTable = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
$result = "";
for ( $i = 0; $i < $length; $i++ ){
$result .= $charTable[ mt_rand(0, strlen($charTable) - 1) ];
}
return $result;
}
public function download($stores, $speed, $policy)
{
$secretId = $policy['config']['secret_id'];
$secretKey = $policy['config']['secret_key'];
$region = $policy['config']['region'];
$bucket = $policy['config']['bucket'];
$object = ltrim($stores['file_name'],'/');
// COS对象
$client = new Client([
'region' => $region,
'schema' => 'http',
'credentials' => [
'secretId' => $secretId,
'secretKey' => $secretKey
]
]);
$disposition = 'attachment; filename='.$stores['origin_name'];
$url = $client->getPresignedUrl('GetObject',[
'Bucket' => $bucket,
'Key' => $object
],'+10 minutes')->__toString();
$url .= 'response-content-disposition='.urlencode($disposition).'&';
// 限速下载
if($speed !== ""){
// 下载速度
$down_speed = round(intval($speed) * 8192);
// 最小限速100kb/s
if($down_speed < 819200){
$down_speed = 819200;
}
$url .= 'x-cos-traffic-limit='.$down_speed;
}
// 跳转下载地址
return redirect($url);
}
}