feat: 新增阿里 oss 上传组件
This commit is contained in:
parent
ef6a1204a9
commit
0351f61038
@ -58,3 +58,9 @@ VITE_PUSHER_PORT="${PUSHER_PORT}"
|
||||
VITE_PUSHER_SCHEME="${PUSHER_SCHEME}"
|
||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||
VITE_BASE_URL=${APP_URL}/api/
|
||||
|
||||
ALIOSS_BUCKET=
|
||||
ALIOSS_ACCESS_ID=
|
||||
ALIOSS_ACCESS_SECRET=
|
||||
ALIOSS_ENDPOINT=
|
||||
ALIOSS_UPLOAD_DIR=
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace Modules\Common\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use Modules\Common\Support\Upload\OssUpload;
|
||||
use Modules\Common\Support\Upload\Uploader;
|
||||
|
||||
/**
|
||||
@ -31,4 +32,16 @@ class UploadController
|
||||
{
|
||||
return $uploader->upload($request->file('image'));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* oss upload
|
||||
*
|
||||
* @param OssUpload $ossUpload
|
||||
* @return array
|
||||
*/
|
||||
public function oss(OssUpload $ossUpload): array
|
||||
{
|
||||
return $ossUpload->config();
|
||||
}
|
||||
}
|
||||
|
101
modules/Common/Support/Upload/OssUpload.php
Normal file
101
modules/Common/Support/Upload/OssUpload.php
Normal file
@ -0,0 +1,101 @@
|
||||
<?php
|
||||
namespace Modules\Common\Support\Upload;
|
||||
|
||||
class OssUpload
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
protected string $dir = 'upload/';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
protected int $expire = 30;
|
||||
|
||||
protected string $accessKeyId;
|
||||
|
||||
protected string $accessKeySecret;
|
||||
|
||||
protected string $endpoint;
|
||||
|
||||
protected int $maxSize;
|
||||
|
||||
protected string $bucket;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->accessKeySecret = config('common.upload.oss.access_secret');
|
||||
|
||||
$this->accessKeyId = config('common.upload.oss.access_id');
|
||||
|
||||
$this->dir = date('Y-m-d') . '/';
|
||||
|
||||
$this->endpoint = config('common.upload.oss.endpoint');
|
||||
|
||||
$this->maxSize = config('common.upload.max_size');
|
||||
|
||||
$this->bucket = config('common.upload.oss.bucket');
|
||||
}
|
||||
|
||||
/**
|
||||
* config
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function config(): array
|
||||
{
|
||||
return [
|
||||
'bucket' => $this->bucket,
|
||||
|
||||
'accessKeyId' => $this->accessKeyId,
|
||||
|
||||
'host' => sprintf('https://%s.%s', $this->bucket, $this->endpoint),
|
||||
|
||||
'policy' => $this->policy(),
|
||||
|
||||
'signature' => $this->signature(),
|
||||
|
||||
'expire' => $this->getExpiration(),
|
||||
|
||||
'dir' => $this->dir,
|
||||
|
||||
'url' => $this->endpoint . $this->dir
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function policy(): string
|
||||
{
|
||||
return base64_encode(json_encode([
|
||||
'expiration' => $this->getExpiration(),
|
||||
'conditions' => [
|
||||
['starts-with', '$key', $this->dir],
|
||||
['content-length-range', 0, $this->maxSize]
|
||||
]
|
||||
]));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function signature(): string
|
||||
{
|
||||
return base64_encode(
|
||||
\hash_hmac('sha1', $this->policy(), $this->accessKeySecret, true)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getExpiration(): string
|
||||
{
|
||||
return date('Y-m-d\TH:i:s\Z', time() + $this->expire);
|
||||
}
|
||||
}
|
18
modules/Common/config/upload.php
Normal file
18
modules/Common/config/upload.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
return [
|
||||
// 文件最大
|
||||
'max_size' => 10 * 1024 * 1024,
|
||||
|
||||
// oss 配置
|
||||
'oss' => [
|
||||
'bucket' => env('ALIOSS_BUCKET'),
|
||||
|
||||
'access_id' => env('ALIOSS_ACCESS_ID'),
|
||||
|
||||
'access_secret' => env('ALIOSS_ACCESS_SECRET'),
|
||||
|
||||
'endpoint' => env('ALIOSS_ENDPOINT'),
|
||||
|
||||
'dir' => env('ALIOSS_UPLOAD_DIR')
|
||||
],
|
||||
];
|
@ -17,6 +17,12 @@ use Modules\Common\Http\Controllers\UploadController;
|
||||
|
||||
Route::get('options/{name}', [OptionController::class, 'index']);
|
||||
|
||||
Route::post('upload/file', [UploadController::class, 'file']);
|
||||
Route::controller(UploadController::class)->group(function (){
|
||||
Route::post('upload/file', 'file');
|
||||
Route::post('upload/image', 'image');
|
||||
// get oss signature
|
||||
Route::get('upload/oss', 'oss');
|
||||
});
|
||||
|
||||
|
||||
|
||||
Route::post('upload/image', [UploadController::class, 'image']);
|
||||
|
59
resources/admin/components/admin/upload/oss.vue
Normal file
59
resources/admin/components/admin/upload/oss.vue
Normal file
@ -0,0 +1,59 @@
|
||||
<template>
|
||||
<el-upload ref="upload" :action="action" :auto-upload="auto" v-bind="$attrs" :data="data" :before-upload="initOss" :on-success="handleSuccess">
|
||||
<template v-for="(index, name) in $slots" v-slot:[name]>
|
||||
<slot :name="name"></slot>
|
||||
</template>
|
||||
</el-upload>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import http from "/admin/support/http"
|
||||
import {ref} from "vue";
|
||||
import Message from "/admin/support/message";
|
||||
const props = defineProps({
|
||||
auto: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
modelValue: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
require: true,
|
||||
},
|
||||
})
|
||||
|
||||
const action = ref('')
|
||||
const data = ref({
|
||||
OSSAccessKeyId: '',
|
||||
policy: '',
|
||||
Signature: '',
|
||||
key: '',
|
||||
host: '',
|
||||
dir: '',
|
||||
expire: '',
|
||||
success_action_status: 200
|
||||
})
|
||||
const emits = defineEmits(['update:modelValue'])
|
||||
const initOss = async (file) => {
|
||||
if (file.size > 10 * 1024 * 1024) {
|
||||
Message.error('最大支持 10MB 文件')
|
||||
return
|
||||
}
|
||||
|
||||
await http.get('upload/oss').then(r => {
|
||||
const {accessKeyId, bucket, dir, expire, host, policy, signature, url} = r.data.data
|
||||
action.value = host
|
||||
data.value.OSSAccessKeyId = accessKeyId
|
||||
data.value.policy = policy
|
||||
data.value.Signature = signature
|
||||
data.value.key = dir + file.name
|
||||
data.value.host = host
|
||||
data.value.dir = dir
|
||||
data.value.expire = expire
|
||||
})
|
||||
}
|
||||
|
||||
const handleSuccess = (r) => {
|
||||
emits('update:modelValue', action.value + data.value.key)
|
||||
}
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user