100 lines
3.8 KiB
JavaScript
100 lines
3.8 KiB
JavaScript
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
const assert_1 = require("oak-domain/lib/utils/assert");
|
|
const Exception_1 = require("../../types/Exception");
|
|
const Exception_2 = require("oak-domain/lib/types/Exception");
|
|
const common_1 = require("./common");
|
|
class S3 {
|
|
name = 's3';
|
|
autoInform() {
|
|
return false;
|
|
}
|
|
getConfig(application) {
|
|
const { system } = application;
|
|
const { config } = system;
|
|
const s3Config = config.Cos?.s3;
|
|
(0, assert_1.assert)(s3Config);
|
|
const { accessKey, endpoint, defaultBucket } = s3Config;
|
|
const account = config.Account?.s3?.find((ele) => ele.accessKey === accessKey);
|
|
(0, assert_1.assert)(account);
|
|
return {
|
|
config: s3Config,
|
|
account,
|
|
endpoint,
|
|
defaultBucket,
|
|
};
|
|
}
|
|
formKey(extraFile) {
|
|
const { id, extension, objectId } = extraFile;
|
|
(0, assert_1.assert)(objectId);
|
|
return `extraFile/${objectId}${extension ? '.' + extension : ''}`;
|
|
}
|
|
async upload(options) {
|
|
const { extraFile, uploadFn, file, getPercent, parallelism, retryTimes, retryDelay, onChunkSuccess } = options;
|
|
const uploadMeta = extraFile.uploadMeta;
|
|
if (extraFile.enableChunkedUpload) {
|
|
return (0, common_1.chunkUpload)({
|
|
extraFile,
|
|
uploadFn,
|
|
file,
|
|
getPercent,
|
|
parallelism: parallelism,
|
|
retryTimes: retryTimes,
|
|
retryDelay: retryDelay,
|
|
onChunkSuccess: onChunkSuccess,
|
|
});
|
|
}
|
|
else {
|
|
let response;
|
|
try {
|
|
// S3 使用预签名 URL 直接上传,不需要额外的 formData
|
|
response = await uploadFn(file, 'file', uploadMeta.uploadUrl, {}, true, getPercent, extraFile.id, "PUT");
|
|
}
|
|
catch (err) {
|
|
throw new Exception_2.OakNetworkException('网络异常,请求失败');
|
|
}
|
|
let isSuccess = false;
|
|
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
|
// 小程序端上传
|
|
if (response.errMsg === 'uploadFile:ok') {
|
|
const statusCode = response.statusCode;
|
|
isSuccess = statusCode === 200 || statusCode === 204;
|
|
}
|
|
}
|
|
else {
|
|
isSuccess = response.status === 200 || response.status === 204;
|
|
}
|
|
if (isSuccess) {
|
|
return;
|
|
}
|
|
}
|
|
throw new Exception_1.OakUploadException('文件上传S3失败');
|
|
}
|
|
composeFileUrl(options) {
|
|
const { application, extraFile, style } = options;
|
|
const { config: s3CosConfig, endpoint } = this.getConfig(application);
|
|
if (s3CosConfig) {
|
|
let bucket = s3CosConfig.buckets.find((ele) => ele.name === extraFile.bucket);
|
|
if (bucket) {
|
|
const { domain, protocol, pathStyle } = bucket;
|
|
let protocol2 = protocol;
|
|
if (protocol instanceof Array) {
|
|
const index = protocol.includes('https:')
|
|
? protocol.findIndex((ele) => ele === 'https:')
|
|
: 0;
|
|
protocol2 = protocol[index];
|
|
}
|
|
const key = this.formKey(extraFile);
|
|
// 如果使用 pathStyle (Minio 常用)
|
|
if (pathStyle && endpoint) {
|
|
return `${protocol2}//${domain}/${bucket.name}/${key}${style ? style : ''}`;
|
|
}
|
|
// 否则使用虚拟主机风格 (AWS S3 默认)
|
|
return `${protocol2}//${domain}/${key}${style ? style : ''}`;
|
|
}
|
|
}
|
|
return '';
|
|
}
|
|
}
|
|
exports.default = S3;
|