阶段更新
This commit is contained in:
45
modules/Storage/Config/config.php
Normal file
45
modules/Storage/Config/config.php
Normal 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 为 false,endpoint 应配置 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', ''),
|
||||
],
|
||||
],
|
||||
|
||||
];
|
||||
@@ -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');
|
||||
}
|
||||
|
||||
}
|
||||
198
modules/Storage/Http/Controllers/OssController.php
Normal file
198
modules/Storage/Http/Controllers/OssController.php
Normal 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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
12
modules/Storage/Models/Storage.php
Normal file
12
modules/Storage/Models/Storage.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace Modules\Storage\Models;
|
||||
|
||||
use App\Models\Model;
|
||||
|
||||
class Storage extends Model
|
||||
{
|
||||
|
||||
protected $table = 'file_storages';
|
||||
|
||||
}
|
||||
51
modules/Storage/Providers/RouteServiceProvider.php
Normal file
51
modules/Storage/Providers/RouteServiceProvider.php
Normal 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'));
|
||||
}
|
||||
|
||||
}
|
||||
69
modules/Storage/Providers/StorageServiceProvider.php
Normal file
69
modules/Storage/Providers/StorageServiceProvider.php
Normal 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 [];
|
||||
}
|
||||
|
||||
}
|
||||
12
modules/Storage/Routes/api.php
Normal file
12
modules/Storage/Routes/api.php
Normal 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');
|
||||
});
|
||||
34
modules/Storage/Storage.php
Normal file
34
modules/Storage/Storage.php
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
34
modules/Storage/composer.json
Normal file
34
modules/Storage/composer.json
Normal 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\\": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
15
modules/Storage/module.json
Normal file
15
modules/Storage/module.json
Normal 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"
|
||||
}
|
||||
Reference in New Issue
Block a user