阶段更新

This commit is contained in:
2023-01-12 14:47:38 +08:00
parent 088dd64b2f
commit 5b8901281c
626 changed files with 39326 additions and 12 deletions

View File

@@ -0,0 +1,45 @@
<?php
return [
// 最大上传文件字节数
'max_upload_size' => 5 * 1024 * 1024,
'upload_path' => 'uploads',
'driver' => env('FILESYSTEM_DRIVER', 'public'),
'disks' => [
'public' => [
'driver' => 'local',
'root' => storage_path('app/public'),
'url' => env('APP_URL') . '/storage',
'visibility' => 'public',
],
'oss' => [
'driver' => 'oss',
'root' => '', // 设置上传时根前缀
'access_key' => env('OSS_ACCESS_KEY'),
'secret_key' => env('OSS_SECRET_KEY'),
'endpoint' => env('OSS_ENDPOINT'), // 使用 ssl 这里设置如: https://oss-cn-beijing.aliyuncs.com
'bucket' => env('OSS_BUCKET'),
'isCName' => env('OSS_IS_CNAME', false),
// 如果 isCname 为 falseendpoint 应配置 oss 提供的域名如:`oss-cn-beijing.aliyuncs.com`否则为自定义域名cname 或 cdn 请自行到阿里 oss 后台配置并绑定 bucket
// 如果有更多的 bucket 需要切换就添加所有bucket默认的 bucket 填写到上面,不要加到 buckets 中
'buckets' => [
'test' => [
'access_key' => env('OSS_ACCESS_KEY'),
'secret_key' => env('OSS_SECRET_KEY'),
'bucket' => env('OSS_TEST_BUCKET'),
'endpoint' => env('OSS_TEST_ENDPOINT'),
'isCName' => env('OSS_TEST_IS_CNAME', false),
],
],
// 以下是STS用的不使用STS直传可不用配置
'RegionId' => env('OSS_STS_REGION_ID', 'cn-beijing'),
'RoleArn' => env('OSS_STS_ROLE_ARN', ''),
],
],
];

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateFileStoragesTable extends Migration
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
Schema::create('file_storages', function (Blueprint $table) {
$table->id();
$table->string('driver', 16);
$table->string('hash', 32)->index();
$table->string('type', 32);
$table->unsignedInteger('size');
$table->string('path');
$table->timestamps();
});
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
Schema::dropIfExists('file_storages');
}
}

View File

@@ -0,0 +1,198 @@
<?php
namespace Modules\Storage\Http\Controllers;
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use App\Api\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Storage;
use Modules\Storage\Models\Storage as StorageModel;
class OssController extends Controller
{
/**
* Notes : 普通文件上传
*
* @Date : 2021/4/25 5:25 下午
* @Author : <Jason.C>
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function upload(Request $request)
{
$upload = $request->file('upload');
$size = File::size($upload->path());
if ($size > Config::get('storage.max_upload_size')) {
return $this->failed('超过最大允许上传大小', 422);
}
$exists = true;
$hash = File::hash($upload->path());
$existFile = StorageModel::where('driver', Config::get('storage.driver'))->where('hash', $hash)->first();
if ($existFile) {
$fullName = $existFile->path;
} else {
$path = Config::get('storage.upload_path').date('/Y/m/d');
$fileName = $hash.'.'.$upload->getClientOriginalExtension();
$fullName = $path.'/'.$fileName;
$uploaded = Storage::putFileAs($path, $upload, $fileName);
if (! $uploaded) {
return $this->failed('文件上传失败', 422);
}
$exists = false;
StorageModel::create([
'hash' => $hash,
'driver' => Config::get('storage.driver'),
'type' => $upload->getClientMimeType(),
'size' => $size,
'path' => $fullName,
]);
}
return $this->success([
'exists' => $exists,
'size' => $size,
'path' => $fullName,
'url' => Storage::url($fullName),
]);
}
/**
* Notes : 多图片统一上传
*
* @Date : 2021/8/23 13:49
* @Author : Mr.wang
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function uploads(Request $request)
{
$fullFile = [];
$files = [];
if ($request->file()) {
$i = 1;
foreach ($request->file() as $key => $upload) {
$size = File::size($upload->path());
if ($size > Config::get('storage.max_upload_size')) {
$message = '上传失败图片大小超过5M';
return $this->failed($message, 422);
}
$hash = File::hash($upload->path());
$existFile = StorageModel::where('driver', Config::get('storage.driver'))
->where('hash', $hash)
->first();
if ($existFile) {
$fullName = $existFile->path;
} else {
$path = Config::get('storage.upload_path').date('/Y/m/d');
$fileName = $hash.'.'.$upload->getClientOriginalExtension();
$fullName = $path.'/'.$fileName;
$uploaded = Storage::putFileAs($path, $upload, $fileName);
if (! $uploaded) {
return $this->failed('文件上传失败', 422);
}
StorageModel::create([
'hash' => $hash,
'driver' => Config::get('storage.driver'),
'type' => $upload->getClientMimeType(),
'size' => $size,
'path' => $fullName,
]);
}
$fullFile[] = Storage::url($fullName);
$files[] = $fullName;
$i++;
}
return $this->success([
'path' => $files,
'url' => $fullFile,
]);
} else {
return $this->failed('没有图片');
}
}
/**
* Notes : STS 授权直传
*
* @Date : 2021/4/25 5:24 下午
* @Author : <Jason.C>
* @return mixed
*/
public function sts()
{
$config = Config::get('storage.disks.oss');
try {
AlibabaCloud::accessKeyClient(
$config['access_key'],
$config['secret_key'],
)->regionId($config['RegionId'])->asDefaultClient();
} catch (ClientException $e) {
return $this->failed($e->getErrorMessage());
}
try {
$Policy = [
'Version' => "1",
'Statement' => [
[
'Effect' => 'Allow',
'Action' => 'oss:*',
'Resource' => [
"*",
],
],
],
];
$result = AlibabaCloud::rpc()
->product('Sts')
->scheme('https') // https | http
->version('2015-04-01')
->action('AssumeRole')
->method('POST')
->host('sts.aliyuncs.com')
->options([
'query' => [
'RegionId' => $config['RegionId'],
'RoleArn' => $config['RoleArn'],
'RoleSessionName' => 'RoleSessionName',
// 'Policy' => json_encode($Policy),
'DurationSeconds' => 3600,
],
])
->request();
return $this->success([
'secure' => true,
'bucket' => $config['bucket'],
'region' => $config['RegionId'], // 前缀带 oss-
'accessKeyId' => $result->Credentials->AccessKeyId,
'accessKeySecret' => $result->Credentials->AccessKeySecret,
'stsToken' => $result->Credentials->SecurityToken,
'endpoint' => $config['endpoint'],
'cname' => $config['isCName'],
]);
} catch (ClientException | ServerException $e) {
return $this->failed($e->getErrorMessage());
}
}
}

View File

@@ -0,0 +1,12 @@
<?php
namespace Modules\Storage\Models;
use App\Models\Model;
class Storage extends Model
{
protected $table = 'file_storages';
}

View File

@@ -0,0 +1,51 @@
<?php
namespace Modules\Storage\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
*/
protected string $moduleName = 'Storage';
/**
* The module namespace to assume when generating URLs to actions.
* @var string
*/
protected string $moduleNamespace = 'Modules\Storage\Http\Controllers';
/**
* Called before routes are registered.
* Register any model bindings or pattern based filters.
* @return void
*/
public function boot()
{
parent::boot();
}
/**
* Define the routes for the application.
* @return void
*/
public function map()
{
$this->mapApiRoutes();
}
protected function mapApiRoutes()
{
Route::as(config('api.route.as'))
->domain(config('api.route.domain'))
->middleware(config('api.route.middleware'))
->namespace($this->moduleNamespace)
->prefix(config('api.route.prefix'))
->group(module_path($this->moduleName, 'Routes/api.php'));
}
}

View File

@@ -0,0 +1,69 @@
<?php
namespace Modules\Storage\Providers;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\ServiceProvider;
class StorageServiceProvider extends ServiceProvider
{
/**
* @var string $moduleName
*/
protected string $moduleName = 'Storage';
/**
* @var string $moduleNameLower
*/
protected string $moduleNameLower = 'storage';
/**
* Boot the application events.
* @return void
*/
public function boot()
{
$this->loadMigrationsFrom(module_path($this->moduleName, 'Database/Migrations'));
}
/**
* Register the service provider.
* @return void
*/
public function register()
{
$this->registerConfig();
$driver = Config::get('storage.driver');
Config::set('filesystems.default', $driver);
$disks = Config::get('storage.disks');
Config::set('filesystems.disks.' . $driver, data_get($disks, $driver));
$this->app->register(RouteServiceProvider::class);
}
/**
* Register config.
* @return void
*/
protected function registerConfig()
{
$this->publishes([
module_path($this->moduleName, 'Config/config.php') => config_path($this->moduleNameLower . '.php'),
], 'config');
$this->mergeConfigFrom(
module_path($this->moduleName, 'Config/config.php'), $this->moduleNameLower
);
}
/**
* Get the services provided by the provider.
* @return array
*/
public function provides(): array
{
return [];
}
}

View File

@@ -0,0 +1,12 @@
<?php
use Illuminate\Routing\Router;
use Illuminate\Support\Facades\Route;
Route::group([
'prefix' => 'storage',
], function (Router $router) {
$router->post('upload', 'OssController@upload');
$router->post('uploads', 'OssController@uploads');
$router->get('sts', 'OssController@sts');
});

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Storage;
use Illuminate\Support\Facades\Artisan;
class Storage
{
protected static string $mainTitle = '文件管理';
/**
* Notes : 模块初始化要做的一些操作
* @Date : 2021/3/12 11:34 上午
* @Author : < Jason.C >
*/
public static function install()
{
Artisan::call('migrate', [
'--path' => 'modules/Storage/Database/Migrations',
]);
}
/**
* Notes : 卸载模块的一些操作
* @Date : 2021/3/12 11:35 上午
* @Author : < Jason.C >
*/
public static function uninstall()
{
}
}

View File

@@ -0,0 +1,34 @@
{
"name": "uztech/storage-storage",
"description": "文件存储模块",
"type": "laravel-module",
"authors": [
{
"name": "Jason.Chen",
"email": "chenjxlg@163.com"
}
],
"require": {
"php": "^7.3|^8.0",
"alibabacloud/sts": "^1.8",
"encore/laravel-admin": "^1.8",
"iidestiny/laravel-filesystem-oss": "^2.1",
"jasonc/api": "^5.0.0",
"joshbrw/laravel-module-installer": "^2.0",
"laravel/framework": "^8.5",
"nwidart/laravel-modules": "^8.2"
},
"extra": {
"module-dir": "modules",
"laravel": {
"providers": [],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"Modules\\Storage\\": ""
}
}
}

View File

@@ -0,0 +1,15 @@
{
"name": "Storage",
"alias": "storage",
"description": "文件存储模块,文件上传,文件管理",
"keywords": [],
"priority": 0,
"providers": [
"Modules\\Storage\\Providers\\StorageServiceProvider"
],
"aliases": {},
"files": [],
"requires": [],
"version": "1.0.0",
"author": "Jason.Chen"
}