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_SCHEME="${PUSHER_SCHEME}"
|
||||||
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
VITE_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
|
||||||
VITE_BASE_URL=${APP_URL}/api/
|
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;
|
namespace Modules\Common\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Modules\Common\Support\Upload\OssUpload;
|
||||||
use Modules\Common\Support\Upload\Uploader;
|
use Modules\Common\Support\Upload\Uploader;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -31,4 +32,16 @@ class UploadController
|
|||||||
{
|
{
|
||||||
return $uploader->upload($request->file('image'));
|
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::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