支持天翼云文件上传
This commit is contained in:
parent
4e6c198648
commit
d199ace4ed
|
|
@ -0,0 +1,16 @@
|
|||
import { ED, BRC, FRC } from '../../types/RuntimeCxt';
|
||||
import Cos from "../../types/Cos";
|
||||
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
|
||||
export default class CTYun implements Cos<ED, BRC, FRC> {
|
||||
name: string;
|
||||
autoInform(): boolean;
|
||||
private formKey;
|
||||
formUploadMeta(extraFile: OpSchema, context: BRC): Promise<void>;
|
||||
upload(extraFile: OpSchema, uploadFn: (file: File | string, name: string, // 文件的part name
|
||||
uploadUrl: string, // 上传的url
|
||||
formData: Record<string, any>, // 上传的其它part参数
|
||||
autoInform?: boolean) => Promise<any>, file: string | File): Promise<void>;
|
||||
composeFileUrl(extraFile: ED['extraFile']['OpSchema'], context: FRC, style?: string): string;
|
||||
checkWhetherSuccess(extraFile: OpSchema, context: BRC): Promise<boolean>;
|
||||
removeFile(extraFile: OpSchema, context: BRC): Promise<void>;
|
||||
}
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const assert_1 = require("oak-domain/lib/utils/assert");
|
||||
const getContextConfig_1 = require("../getContextConfig");
|
||||
const Exception_1 = require("../../types/Exception");
|
||||
const oak_domain_1 = require("oak-domain");
|
||||
class CTYun {
|
||||
name = 'ctyun';
|
||||
autoInform() {
|
||||
return false;
|
||||
}
|
||||
formKey(extraFile) {
|
||||
const { id, extension, objectId } = extraFile;
|
||||
(0, assert_1.assert)(objectId);
|
||||
return `extraFile/${objectId}${extension ? '.' + extension : ''}`;
|
||||
}
|
||||
async formUploadMeta(extraFile, context) {
|
||||
const { bucket } = extraFile;
|
||||
// 构造文件上传所需的key
|
||||
const key = this.formKey(extraFile);
|
||||
const { instance, config } = (0, getContextConfig_1.getConfig)(context, 'Cos', 'ctyun');
|
||||
const { buckets } = config;
|
||||
let bucket2 = bucket;
|
||||
if (!bucket2) {
|
||||
const { defaultBucket } = config;
|
||||
bucket2 = defaultBucket;
|
||||
}
|
||||
(0, assert_1.assert)(bucket2);
|
||||
const b = buckets.find(ele => ele.name === bucket2);
|
||||
(0, assert_1.assert)(b, `${bucket2}不是一个有效的桶配置`);
|
||||
Object.assign(extraFile, {
|
||||
bucket: bucket2,
|
||||
uploadMeta: instance.getUploadInfo(bucket2, b.zone, key),
|
||||
});
|
||||
}
|
||||
async upload(extraFile, uploadFn, file) {
|
||||
const uploadMeta = extraFile.uploadMeta;
|
||||
let result;
|
||||
try {
|
||||
result = await uploadFn(file, 'file', uploadMeta.uploadHost, {
|
||||
Key: uploadMeta.key,
|
||||
Policy: uploadMeta.policy,
|
||||
AWSAccessKeyId: uploadMeta.accessKey,
|
||||
signature: uploadMeta.signature,
|
||||
}, true);
|
||||
}
|
||||
catch (err) {
|
||||
// 网络错误
|
||||
throw new oak_domain_1.OakNetworkException('网络异常,请求失败');
|
||||
}
|
||||
let isSuccess = false;
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
||||
// 小程序端上传 使用wx.uploadFile
|
||||
if (result.errMsg === 'uploadFile:ok') {
|
||||
const jsonData = JSON.parse(result.data);
|
||||
isSuccess = !!jsonData.key;
|
||||
}
|
||||
}
|
||||
else {
|
||||
isSuccess = !!(result.success === true || result.key);
|
||||
}
|
||||
// 解析回调
|
||||
if (isSuccess) {
|
||||
return;
|
||||
}
|
||||
else {
|
||||
throw new Exception_1.OakUploadException('图片上传七牛失败');
|
||||
}
|
||||
}
|
||||
composeFileUrl(extraFile, context, style) {
|
||||
const { config } = (0, getContextConfig_1.getConfig)(context, 'Cos', 'qiniu');
|
||||
if (config) {
|
||||
let bucket = config.buckets.find((ele) => ele.name === extraFile.bucket);
|
||||
if (bucket) {
|
||||
const { domain, protocol } = bucket;
|
||||
let protocol2 = protocol;
|
||||
if (protocol instanceof Array) {
|
||||
// protocol存在https 说明域名有证书
|
||||
const index = protocol.includes('https')
|
||||
? protocol.findIndex((ele) => ele === 'https')
|
||||
: 0;
|
||||
protocol2 = protocol[index];
|
||||
}
|
||||
return `${protocol2}://${domain}/${this.formKey(extraFile)}`;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
async checkWhetherSuccess(extraFile, context) {
|
||||
return true;
|
||||
}
|
||||
async removeFile(extraFile, context) {
|
||||
}
|
||||
}
|
||||
exports.default = CTYun;
|
||||
;
|
||||
|
|
@ -12,6 +12,7 @@ type BeforeCommit =
|
|||
| undefined;
|
||||
|
||||
export default OakComponent({
|
||||
isList: false,
|
||||
formData({ features }) {
|
||||
const ids: string[] = this.getEfIds();
|
||||
const states = ids.map((id) => features.extraFile.getFileState(id));
|
||||
|
|
|
|||
|
|
@ -1,10 +1,15 @@
|
|||
import { QiniuZone } from 'oak-external-sdk';
|
||||
import { QiniuZone, CTYunZone } from 'oak-external-sdk';
|
||||
|
||||
export type QiniuCloudConfig = {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
};
|
||||
|
||||
export type CTYunConfig = {
|
||||
accessKey: string;
|
||||
secretKey: string;
|
||||
}
|
||||
|
||||
export type QiniuLiveConfig = {
|
||||
accessKey: string;
|
||||
liveHost: string; // 七牛直播云接口域名
|
||||
|
|
@ -27,6 +32,17 @@ export type QiniuCosConfig = {
|
|||
defaultBucket: string; // 默认上传桶
|
||||
}
|
||||
|
||||
export type CTYunCosConfig = {
|
||||
accessKey: string;
|
||||
buckets: { // 七牛配置的桶信息
|
||||
zone: CTYunZone; // 七牛存储区域(https://developer.qiniu.com/kodo/1671/region-endpoint-fq)
|
||||
name: string;
|
||||
domain: string;
|
||||
protocol: string | string[];
|
||||
}[];
|
||||
defaultBucket: string; // 默认上传桶
|
||||
}
|
||||
|
||||
export type AmapMapConfig = {
|
||||
webApiKey: string;
|
||||
};
|
||||
|
|
@ -84,10 +100,12 @@ export type Config = {
|
|||
ali?: AliCloudConfig[];
|
||||
tencent?: TencentCloudConfig[];
|
||||
qiniu?: QiniuCloudConfig[];
|
||||
ctyun?: CTYunConfig[];
|
||||
amap?: AmapCloudConfig[];
|
||||
};
|
||||
Cos?: {
|
||||
qiniu?: QiniuCosConfig;
|
||||
ctyun?: CTYunCosConfig;
|
||||
};
|
||||
Live?: {
|
||||
qiniu?: QiniuLiveConfig;
|
||||
|
|
@ -109,5 +127,5 @@ export type Config = {
|
|||
};
|
||||
};
|
||||
|
||||
export type Origin = 'ali' | 'tencent' | 'qiniu' | 'amap';
|
||||
export type Origin = 'ali' | 'tencent' | 'qiniu' | 'amap' | 'ctyun';
|
||||
export type Service = 'Map' | 'Cos' | 'Live' | 'Sms';
|
||||
|
|
@ -4,6 +4,15 @@ export type QiniuUploadInfo = {
|
|||
uploadHost: string;
|
||||
bucket: string;
|
||||
};
|
||||
export type CTYunUploadInfo = {
|
||||
key?: string;
|
||||
accessKey: string;
|
||||
uploadToken: string;
|
||||
uploadHost: string;
|
||||
policy: string;
|
||||
signature: string;
|
||||
bucket: string;
|
||||
};
|
||||
|
||||
export type AliyunUploadInfo = {
|
||||
key?: string;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,142 @@
|
|||
import { ED, BRC, FRC } from '../../types/RuntimeCxt';
|
||||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import Cos from "../../types/Cos";
|
||||
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
|
||||
|
||||
import { CTYunUploadInfo } from '../../types/Upload';
|
||||
import { getConfig } from '../getContextConfig';
|
||||
import { CTYunCosConfig } from '../../types/Config';
|
||||
import { CTYunInstance } from 'oak-external-sdk';
|
||||
import { urlSafeBase64Encode } from '../sign';
|
||||
import { OakUploadException } from '../../types/Exception';
|
||||
import { OakExternalException, OakNetworkException } from 'oak-domain';
|
||||
|
||||
export default class CTYun implements Cos<ED, BRC, FRC> {
|
||||
name = 'ctyun';
|
||||
|
||||
autoInform(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
private formKey(extraFile: OpSchema) {
|
||||
const { id, extension, objectId } = extraFile;
|
||||
|
||||
assert(objectId);
|
||||
return `extraFile/${objectId}${extension ? '.' + extension : ''}`;
|
||||
}
|
||||
|
||||
async formUploadMeta(
|
||||
extraFile: OpSchema,
|
||||
context: BRC
|
||||
) {
|
||||
const { bucket } = extraFile;
|
||||
// 构造文件上传所需的key
|
||||
const key = this.formKey(extraFile);
|
||||
const { instance, config } = getConfig<ED, BRC, FRC>(context, 'Cos', 'ctyun');
|
||||
|
||||
const { buckets } = config as CTYunCosConfig;
|
||||
let bucket2 = bucket;
|
||||
if (!bucket2) {
|
||||
const { defaultBucket } = config as CTYunCosConfig;
|
||||
bucket2 = defaultBucket!;
|
||||
}
|
||||
assert(bucket2);
|
||||
const b = buckets.find(ele => ele.name === bucket2);
|
||||
assert(b, `${bucket2}不是一个有效的桶配置`);
|
||||
Object.assign(extraFile, {
|
||||
bucket: bucket2,
|
||||
uploadMeta: (instance as CTYunInstance).getUploadInfo(
|
||||
bucket2,
|
||||
b.zone,
|
||||
key
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
async upload(
|
||||
extraFile: OpSchema,
|
||||
uploadFn: (
|
||||
file: File | string,
|
||||
name: string, // 文件的part name
|
||||
uploadUrl: string, // 上传的url
|
||||
formData: Record<string, any>, // 上传的其它part参数
|
||||
autoInform?: boolean // 上传成功是否会自动通知server(若不会则需要前台显式通知)
|
||||
) => Promise<any>,
|
||||
file: string | File
|
||||
) {
|
||||
const uploadMeta = extraFile.uploadMeta! as CTYunUploadInfo;
|
||||
let result;
|
||||
try {
|
||||
result = await uploadFn(
|
||||
file,
|
||||
'file',
|
||||
uploadMeta.uploadHost,
|
||||
{
|
||||
Key: uploadMeta.key,
|
||||
Policy: uploadMeta.policy,
|
||||
AWSAccessKeyId: uploadMeta.accessKey,
|
||||
signature: uploadMeta.signature,
|
||||
},
|
||||
true
|
||||
);
|
||||
} catch (err) {
|
||||
// 网络错误
|
||||
throw new OakNetworkException('网络异常,请求失败');
|
||||
}
|
||||
let isSuccess = false;
|
||||
if (process.env.OAK_PLATFORM === 'wechatMp') {
|
||||
// 小程序端上传 使用wx.uploadFile
|
||||
if (result.errMsg === 'uploadFile:ok') {
|
||||
const jsonData = JSON.parse(result.data);
|
||||
isSuccess = !!jsonData.key;
|
||||
}
|
||||
}
|
||||
else {
|
||||
isSuccess = !!(result.success === true || result.key);
|
||||
}
|
||||
// 解析回调
|
||||
if (isSuccess) {
|
||||
return;
|
||||
} else {
|
||||
throw new OakUploadException('图片上传七牛失败');
|
||||
}
|
||||
}
|
||||
|
||||
composeFileUrl(
|
||||
extraFile: ED['extraFile']['OpSchema'],
|
||||
context: FRC,
|
||||
style?: string,
|
||||
) {
|
||||
const { config } = getConfig<ED, BRC, FRC>(context, 'Cos', 'qiniu');
|
||||
|
||||
if (config) {
|
||||
let bucket = (config.buckets as CTYunCosConfig['buckets']).find((ele) => ele.name === extraFile.bucket!);
|
||||
if (bucket) {
|
||||
const { domain, protocol } = bucket!;
|
||||
let protocol2 = protocol;
|
||||
if (protocol instanceof Array) {
|
||||
// protocol存在https 说明域名有证书
|
||||
const index = (protocol as ['http', 'https']).includes(
|
||||
'https'
|
||||
)
|
||||
? protocol.findIndex((ele) => ele === 'https')
|
||||
: 0;
|
||||
protocol2 = protocol[index];
|
||||
}
|
||||
return `${protocol2}://${domain}/${this.formKey(extraFile)}`;
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
async checkWhetherSuccess(
|
||||
extraFile: OpSchema,
|
||||
context: BRC
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
async removeFile(extraFile: OpSchema, context: BRC) {
|
||||
}
|
||||
};
|
||||
|
|
@ -9,13 +9,16 @@ import { ED, BRC, FRC } from '../../types/RuntimeCxt';
|
|||
import Cos from '../../types/Cos';
|
||||
import Qiniu from './qiniu';
|
||||
import Wechat from './wechat';
|
||||
import CTYun from './ctyun';
|
||||
|
||||
const ctyun = new CTYun();
|
||||
const qiniu = new Qiniu();
|
||||
const wechat = new Wechat();
|
||||
|
||||
const CosDict: Record<string, any> = {
|
||||
[qiniu.name]: qiniu,
|
||||
[wechat.name]: wechat,
|
||||
[ctyun.name]: ctyun,
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { assert } from 'oak-domain/lib/utils/assert';
|
||||
import { OakDataException } from 'oak-domain/lib/types/Exception';
|
||||
import { AmapSDK, QiniuSDK } from 'oak-external-sdk';
|
||||
import { AmapSDK, QiniuSDK, CTYunSDk } from 'oak-external-sdk';
|
||||
import {
|
||||
AliCloudConfig,
|
||||
AmapCloudConfig,
|
||||
|
|
@ -9,6 +9,7 @@ import {
|
|||
QiniuCloudConfig,
|
||||
Service,
|
||||
TencentCloudConfig,
|
||||
CTYunConfig
|
||||
} from '../types/Config';
|
||||
import { BackendRuntimeContext } from '../context/BackendRuntimeContext';
|
||||
import { FrontendRuntimeContext, AspectDict } from '../context/FrontendRuntimeContext';
|
||||
|
|
@ -87,6 +88,23 @@ export function getConfig<
|
|||
config: originConfig,
|
||||
};
|
||||
}
|
||||
case 'ctyun': {
|
||||
const ctyunAccount = (
|
||||
originCloudAccounts as CTYunConfig[]
|
||||
).find((ele) => ele.accessKey === originConfig.accessKey);
|
||||
assert(
|
||||
ctyunAccount,
|
||||
`调用的服务${service}源${origin}找不到相应的云平台帐号,请联系管理员`
|
||||
);
|
||||
const ctyunInstance = CTYunSDk.getInstance(
|
||||
ctyunAccount!.accessKey,
|
||||
ctyunAccount!.secretKey,
|
||||
);
|
||||
return {
|
||||
instance: ctyunInstance,
|
||||
config: originConfig,
|
||||
};
|
||||
}
|
||||
default: {
|
||||
assert(origin === 'amap');
|
||||
const amapAccount = (originCloudAccounts as AmapCloudConfig[]).find(
|
||||
|
|
|
|||
Loading…
Reference in New Issue