feat: 重构了cos相关的调用方法,并在前端的COS中传入了cache

This commit is contained in:
Pan Qiancheng 2025-12-02 14:10:02 +08:00
parent 68b3f93e9f
commit 6a49d6f5af
20 changed files with 379 additions and 159 deletions

View File

@ -102,10 +102,12 @@ export class ExtraFile<ED extends EntityDict> extends Feature {
const cos = getCos<ED>(extraFile.origin!); const cos = getCos<ED>(extraFile.origin!);
try { try {
await cos.upload( await cos.upload(
extraFile as OpSchema, {
up.uploadFile, extraFile: extraFile as OpSchema,
file, uploadFn: up.uploadFile,
this.uploadToAspect.bind(this) file: file,
uploadToAspect: this.uploadToAspect.bind(this),
}
); );
} catch (err) { } catch (err) {
item.state = 'failed'; item.state = 'failed';
@ -169,12 +171,15 @@ export class ExtraFile<ED extends EntityDict> extends Feature {
if (!origin) { if (!origin) {
return "unknown" return "unknown"
} }
const cos = getCos<ED>(origin!); const cos = getCos<ED>(origin!);
return cos.composeFileUrl( return cos.composeFileUrl(
this.application.getApplication() as EntityDict['application']['Schema'], {
extraFile as EntityDict['extraFile']['OpSchema'], application: this.application.getApplication() as EntityDict['application']['Schema'],
style extraFile: extraFile as EntityDict['extraFile']['OpSchema'],
style: style,
cache: this.cache,
}
); );
} }
@ -228,11 +233,13 @@ export class ExtraFile<ED extends EntityDict> extends Feature {
try { try {
const cos = getCos<ED>(newExtraFile.origin!); const cos = getCos<ED>(newExtraFile.origin!);
await cos.upload( await cos.upload(
newExtraFile as OpSchema, {
up.uploadFile, extraFile: newExtraFile as OpSchema,
file, uploadFn: up.uploadFile,
this.uploadToAspect.bind(this), file: file,
getPercent, uploadToAspect: this.uploadToAspect.bind(this),
getPercent: getPercent,
}
); );
if (!cos.autoInform()) { if (!cos.autoInform()) {
await this.cache.exec('operate', { await this.cache.exec('operate', {

View File

@ -1,5 +1,6 @@
import { EntityDict } from '../oak-app-domain'; import { EntityDict } from '../oak-app-domain';
import { BRC } from '..'; import { BRC } from '..';
import { Cache } from 'oak-frontend-base/es/features/cache'
export type UploadFn = ( export type UploadFn = (
file: File | string, file: File | string,
@ -41,20 +42,25 @@ export interface Cos<ED extends EntityDict> {
* @returns * @returns
*/ */
upload: ( upload: (
extraFile: ED['extraFile']['OpSchema'], options: {
uploadFn: UploadFn, extraFile: ED['extraFile']['OpSchema'],
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function, uploadToAspect?: UploadToAspect,
getPercent?: Function,
}
) => Promise<void>; ) => Promise<void>;
/** /**
* 访urlurl应当和objectId一对一映射extraFile之间共享cos上的路径 * 访urlurl应当和objectId一对一映射extraFile之间共享cos上的路径
*/ */
composeFileUrl: ( composeFileUrl: (
application: Partial<ED['application']['Schema']>, options: {
extraFile: Partial<ED['extraFile']['OpSchema']>, application: Partial<ED['application']['Schema']>,
style?: string, extraFile: Partial<ED['extraFile']['OpSchema']>,
cache: Cache<ED>,
style?: string,
}
) => string; ) => string;
} }
@ -79,10 +85,12 @@ export interface CosBackend<ED extends EntityDict> {
* 访urlurl应当和objectId一对一映射extraFile之间共享cos上的路径 * 访urlurl应当和objectId一对一映射extraFile之间共享cos上的路径
*/ */
composeFileUrlBackend: ( composeFileUrlBackend: (
application: ED['application']['Schema'], options: {
extraFile: ED['extraFile']['OpSchema'], application: ED['application']['Schema'],
context: BRC<ED>, extraFile: ED['extraFile']['OpSchema'],
style?: string, context: BRC<ED>,
style?: string,
}
) => Promise<string>; ) => Promise<string>;
/** /**

View File

@ -4,15 +4,14 @@ import { CosBackend } from '../../types/Cos';
import ALiYun from './aliyun'; import ALiYun from './aliyun';
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema'; import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
import { ALiYunCosConfig } from '../../types/Config'; import { ALiYunCosConfig, Protocol } from '../../types/Config';
import { ALiYunInstance, ALiYunSDK } from 'oak-external-sdk'; import { ALiYunInstance, ALiYunSDK } from 'oak-external-sdk';
import { OakExternalException } from 'oak-domain/lib/types/Exception'; import { OakExternalException } from 'oak-domain/lib/types/Exception';
import { BRC } from '../..'; import { BRC } from '../..';
export default class ALiYunBackend export default class ALiYunBackend
extends ALiYun extends ALiYun
implements CosBackend<EntityDict> implements CosBackend<EntityDict> {
{
private getConfigAndInstance( private getConfigAndInstance(
application: EntityDict['application']['Schema'] application: EntityDict['application']['Schema']
) { ) {
@ -28,14 +27,36 @@ export default class ALiYunBackend
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
extraFile: OpSchema, application: EntityDict['application']['Schema'],
context: BRC<EntityDict>, extraFile: OpSchema,
style?: string context: BRC<EntityDict>,
style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
const { config: aliyunCosConfig } = this.getConfig(application);
if (aliyunCosConfig) {
let bucket = (
aliyunCosConfig.buckets as ALiYunCosConfig['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 Protocol[]).includes('https:')
? protocol.findIndex((ele) => ele === 'https:')
: 0;
protocol2 = protocol[index];
}
return `${protocol2}//${domain}/${this.formKey(extraFile)}${style ? style : ''}`;
}
}
return '';
} }
async formUploadMeta( async formUploadMeta(
application: EntityDict['application']['Schema'], application: EntityDict['application']['Schema'],
extraFile: OpSchema extraFile: OpSchema

View File

@ -36,15 +36,18 @@ export default class ALiYun implements Cos<EntityDict> {
assert(objectId); assert(objectId);
return `extraFile/${objectId}${extension ? '.' + extension : ''}`; return `extraFile/${objectId}${extension ? '.' + extension : ''}`;
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
const uploadMeta = extraFile.uploadMeta! as AliYunUploadInfo; const uploadMeta = extraFile.uploadMeta! as AliYunUploadInfo;
let response; let response;
try { try {
@ -85,10 +88,13 @@ export default class ALiYun implements Cos<EntityDict> {
} }
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string //多媒体样式
}
) { ) {
const { application, extraFile, style } = options;
const { config: aliyunCosConfig } = this.getConfig(application); const { config: aliyunCosConfig } = this.getConfig(application);
if (aliyunCosConfig) { if (aliyunCosConfig) {

View File

@ -4,14 +4,13 @@ import { CosBackend } from '../../types/Cos';
import CTYun from './ctyun'; import CTYun from './ctyun';
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema'; import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
import { CTYunCosConfig } from '../../types/Config'; import { CTYunCosConfig, Protocol } from '../../types/Config';
import { CTYunInstance, CTYunSDK } from 'oak-external-sdk'; import { CTYunInstance, CTYunSDK } from 'oak-external-sdk';
import { BRC } from '../..'; import { BRC } from '../..';
export default class CTYunBackend export default class CTYunBackend
extends CTYun extends CTYun
implements CosBackend<EntityDict> implements CosBackend<EntityDict> {
{
private getConfigAndInstance( private getConfigAndInstance(
application: EntityDict['application']['Schema'] application: EntityDict['application']['Schema']
) { ) {
@ -27,12 +26,34 @@ export default class CTYunBackend
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
extraFile: OpSchema, application: EntityDict['application']['Schema'],
context: BRC<EntityDict>, extraFile: OpSchema,
style?: string context: BRC<EntityDict>,
style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
const { config: ctYunCosConfig } = this.getConfig(application);
if (ctYunCosConfig) {
let bucket = (
ctYunCosConfig.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 Protocol[]).includes('https:')
? protocol.findIndex((ele) => ele === 'https:')
: 0;
protocol2 = protocol[index];
}
return `${protocol2}//${domain}/${this.formKey(extraFile)}${style ? style : ''}`;
}
}
return '';
} }
async formUploadMeta( async formUploadMeta(

View File

@ -39,12 +39,15 @@ export default class CTYun implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
const uploadMeta = extraFile.uploadMeta! as CTYunUploadInfo; const uploadMeta = extraFile.uploadMeta! as CTYunUploadInfo;
let response; let response;
try { try {
@ -93,10 +96,13 @@ export default class CTYun implements Cos<EntityDict> {
// 转换格式(如.jpg是指定图片转换的输出格式通过指定转换格式可以对原图处理并返回指定的图片格式。支持的转换格式为 jpg、webp、png、bmp。 // 转换格式(如.jpg是指定图片转换的输出格式通过指定转换格式可以对原图处理并返回指定的图片格式。支持的转换格式为 jpg、webp、png、bmp。
// 对象存储文档 https://www.ctyun.cn/document/10026693/10026878 // 对象存储文档 https://www.ctyun.cn/document/10026693/10026878
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string //多媒体样式
}
) { ) {
const { application, extraFile, style } = options;
const { config: ctYunCosConfig } = this.getConfig(application); const { config: ctYunCosConfig } = this.getConfig(application);
if (ctYunCosConfig) { if (ctYunCosConfig) {

View File

@ -45,5 +45,7 @@ export async function composeFileUrlBackend<ED extends EntityDict>(
) { ) {
const { origin } = extraFile; const { origin } = extraFile;
const cos = CosBackendDict[origin]; const cos = CosBackendDict[origin];
return cos.composeFileUrlBackend(application, extraFile, context, style); return cos.composeFileUrlBackend({
application, extraFile, context, style
});
} }

View File

@ -1,8 +1,8 @@
import { assert } from 'oak-domain/lib/utils/assert'; import { assert } from 'oak-domain/lib/utils/assert';
import { EntityDict } from '../../oak-app-domain'; import { EntityDict } from '../../oak-app-domain';
import { Cache } from 'oak-frontend-base/es/features/cache'
import { Cos } from '../../types/Cos'; import { Cos } from '../../types/Cos';
import { Config } from '../../types/Config';
import UnknownFrontend from './unknown'; import UnknownFrontend from './unknown';
const CosDict: Record<string, Cos<EntityDict>> = { const CosDict: Record<string, Cos<EntityDict>> = {
@ -24,11 +24,14 @@ export function getCos<ED extends EntityDict>(origin: string) {
} }
export function composeFileUrl<ED extends EntityDict>( export function composeFileUrl<ED extends EntityDict>(
application: Partial<ED['application']['Schema']>, options: {
extraFile: Partial<ED['extraFile']['OpSchema']>, application: Partial<ED['application']['Schema']>,
style?: string extraFile: Partial<ED['extraFile']['OpSchema']>,
style?: string
cache: Cache<ED>,
}
) { ) {
const { origin } = extraFile; const { origin } = options.extraFile;
const cos = CosDict[origin!]; const cos = CosDict[origin!] as Cos<ED>;
return cos.composeFileUrl(application, extraFile, style); return cos.composeFileUrl(options);
} }

View File

@ -3,7 +3,7 @@ import { assert } from 'oak-domain/lib/utils/assert';
import { CosBackend } from "../../types/Cos"; import { CosBackend } from "../../types/Cos";
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema'; import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
import { LocalInstance, LocalSDK } from 'oak-external-sdk'; import { LocalInstance, LocalSDK } from 'oak-external-sdk';
import { LocalCosConfig } from '../../types/Config'; import { LocalCosConfig, Protocol } from '../../types/Config';
import Local from './local'; import Local from './local';
import { BRC } from '../..'; import { BRC } from '../..';
@ -24,12 +24,31 @@ export default class LocalBackend extends Local implements CosBackend<EntityDict
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
extraFile: OpSchema, application: EntityDict['application']['Schema'],
context: BRC<EntityDict>, extraFile: OpSchema,
style?: string context: BRC<EntityDict>,
style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
const { config: localConfig } = this.getConfig(application);
let bucket = (localConfig.buckets as LocalCosConfig['buckets']).find((ele) => ele.name === extraFile.bucket!);
if (bucket) {
const { domain, protocol, nginxPath } = bucket!;
let protocol2 = protocol;
if (protocol instanceof Array) {
// protocol存在https: 说明域名有证书
const index = (protocol as Protocol[]).includes('https:')
? protocol.findIndex((ele) => ele === 'https:')
: 0;
protocol2 = protocol[index];
}
return `${protocol2}//${domain}${nginxPath ? '/' + nginxPath : ''}/${this.formKey(extraFile)}${style ? style : ''}`;
}
return '';
} }
async formUploadMeta( async formUploadMeta(
@ -58,7 +77,7 @@ export default class LocalBackend extends Local implements CosBackend<EntityDict
key, key,
), ),
}); });
} }
async checkWhetherSuccess( async checkWhetherSuccess(
@ -72,6 +91,6 @@ export default class LocalBackend extends Local implements CosBackend<EntityDict
application: EntityDict['application']['Schema'], application: EntityDict['application']['Schema'],
extraFile: OpSchema extraFile: OpSchema
) { ) {
} }
}; };

View File

@ -29,7 +29,7 @@ export default class Local implements Cos<EntityDict> {
(ele) => ele.accessKey === accessKey (ele) => ele.accessKey === accessKey
); );
assert(account); assert(account);
return { return {
config: localConfig, config: localConfig,
account account
@ -44,12 +44,17 @@ export default class Local implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
let result: response; let result: response;
const { applicationId, type, extra2, id } = extraFile; const { applicationId, type, extra2, id } = extraFile;
try { try {
@ -76,10 +81,13 @@ export default class Local implements Cos<EntityDict> {
} }
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string //多媒体样式 extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string //多媒体样式
}
) { ) {
const { application, extraFile, style } = options;
const { config: localConfig } = this.getConfig(application); const { config: localConfig } = this.getConfig(application);
let bucket = (localConfig.buckets as LocalCosConfig['buckets']).find((ele) => ele.name === extraFile.bucket!); let bucket = (localConfig.buckets as LocalCosConfig['buckets']).find((ele) => ele.name === extraFile.bucket!);

View File

@ -3,7 +3,7 @@ import { assert } from 'oak-domain/lib/utils/assert';
import { CosBackend } from "../../types/Cos"; import { CosBackend } from "../../types/Cos";
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema'; import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
import { QiniuCosConfig } from '../../types/Config'; import { Protocol, QiniuCosConfig } from '../../types/Config';
import { QiniuCloudInstance, QiniuSDK } from 'oak-external-sdk'; import { QiniuCloudInstance, QiniuSDK } from 'oak-external-sdk';
import Qiniu from './qiniu'; import Qiniu from './qiniu';
import { OakExternalException } from 'oak-domain/lib/types/Exception'; import { OakExternalException } from 'oak-domain/lib/types/Exception';
@ -21,17 +21,41 @@ export default class QiniuBackend extends Qiniu implements CosBackend<EntityDict
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
extraFile: OpSchema, application: EntityDict['application']['Schema'],
context: BRC<EntityDict>, extraFile: OpSchema,
style?: string context: BRC<EntityDict>,
style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
const { config: qiniuCosConfig } = this.getConfig(application);
if (qiniuCosConfig) {
let bucket = (
qiniuCosConfig.buckets as QiniuCosConfig['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 Protocol[]).includes('https:')
? protocol.findIndex((ele) => ele === 'https:')
: 0;
protocol2 = protocol[index];
}
return `${protocol2}//${domain}/${this.formKey(extraFile)}${style ? style : ''
}`;
}
}
return '';
} }
async formUploadMeta( async formUploadMeta(
application: EntityDict['application']['Schema'], application: EntityDict['application']['Schema'],
extraFile: OpSchema) { extraFile: OpSchema
){
const { bucket } = extraFile; const { bucket } = extraFile;
// 构造文件上传所需的key // 构造文件上传所需的key
const key = this.formKey(extraFile); const key = this.formKey(extraFile);

View File

@ -39,12 +39,15 @@ export default class Qiniu implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
const uploadMeta = extraFile.uploadMeta! as QiniuUploadInfo; const uploadMeta = extraFile.uploadMeta! as QiniuUploadInfo;
let response; let response;
try { try {
@ -89,10 +92,13 @@ export default class Qiniu implements Cos<EntityDict> {
// "-"是默认的样式分隔符, // "-"是默认的样式分隔符,
// 查看文档 https://developer.qiniu.com/kodo/8558/set-the-picture-style // 查看文档 https://developer.qiniu.com/kodo/8558/set-the-picture-style
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string //多媒体样式 extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string //多媒体样式
}
) { ) {
const { application, extraFile, style } = options;
const { config: qiniuCosConfig } = this.getConfig(application); const { config: qiniuCosConfig } = this.getConfig(application);
if (qiniuCosConfig) { if (qiniuCosConfig) {
@ -109,9 +115,8 @@ export default class Qiniu implements Cos<EntityDict> {
: 0; : 0;
protocol2 = protocol[index]; protocol2 = protocol[index];
} }
return `${protocol2}//${domain}/${this.formKey(extraFile)}${ return `${protocol2}//${domain}/${this.formKey(extraFile)}${style ? style : ''
style ? style : '' }`;
}`;
} }
} }
return ''; return '';

View File

@ -4,7 +4,7 @@ import { CosBackend } from '../../types/Cos';
import S3 from './s3'; import S3 from './s3';
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema'; import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
import { S3CosConfig, S3Zone } from '../../types/Config'; import { Protocol, S3CosConfig, S3Zone } from '../../types/Config';
import { S3Instance, S3SDK } from 'oak-external-sdk'; import { S3Instance, S3SDK } from 'oak-external-sdk';
import { OakExternalException } from 'oak-domain/lib/types/Exception'; import { OakExternalException } from 'oak-domain/lib/types/Exception';
import { BRC } from '../..'; import { BRC } from '../..';
@ -39,12 +39,44 @@ export default class S3Backend extends S3 implements CosBackend<EntityDict> {
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
application: EntityDict['application']['Schema'],
extraFile: OpSchema, extraFile: OpSchema,
context: BRC<EntityDict>, context: BRC<EntityDict>,
style?: string style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style)
const { application, extraFile, context, style } = options;
const { config: s3CosConfig, endpoint } = this.getConfig(application);
if (s3CosConfig) {
let bucket = (
s3CosConfig.buckets as 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 as 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 '';
} }
async formUploadMeta( async formUploadMeta(
@ -64,7 +96,7 @@ export default class S3Backend extends S3 implements CosBackend<EntityDict> {
assert(bucket2); assert(bucket2);
const b = buckets.find((ele) => ele.name === bucket2); const b = buckets.find((ele) => ele.name === bucket2);
assert(b, `${bucket2}不是一个有效的桶配置`); assert(b, `${bucket2}不是一个有效的桶配置`);
try { try {
const uploadInfo = await (instance as S3Instance).getUploadInfo( const uploadInfo = await (instance as S3Instance).getUploadInfo(
bucket2, bucket2,
@ -72,7 +104,7 @@ export default class S3Backend extends S3 implements CosBackend<EntityDict> {
endpoint, endpoint,
b.pathStyle b.pathStyle
); );
Object.assign(extraFile, { Object.assign(extraFile, {
bucket: bucket2, bucket: bucket2,
uploadMeta: uploadInfo, uploadMeta: uploadInfo,
@ -129,7 +161,7 @@ export default class S3Backend extends S3 implements CosBackend<EntityDict> {
b, b,
`extraFile中的bucket名称在S3配置中找不到「${extraFile.bucket}` `extraFile中的bucket名称在S3配置中找不到「${extraFile.bucket}`
); );
try { try {
await (instance as S3Instance).removeFile( await (instance as S3Instance).removeFile(
extraFile.bucket!, extraFile.bucket!,

View File

@ -41,12 +41,16 @@ export default class S3 implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
const uploadMeta = extraFile.uploadMeta! as S3UploadInfo; const uploadMeta = extraFile.uploadMeta! as S3UploadInfo;
let response; let response;
try { try {
@ -64,7 +68,7 @@ export default class S3 implements Cos<EntityDict> {
} catch (err) { } catch (err) {
throw new OakNetworkException('网络异常,请求失败'); throw new OakNetworkException('网络异常,请求失败');
} }
let isSuccess = false; let isSuccess = false;
if (process.env.OAK_PLATFORM === 'wechatMp') { if (process.env.OAK_PLATFORM === 'wechatMp') {
// 小程序端上传 // 小程序端上传
@ -75,7 +79,7 @@ export default class S3 implements Cos<EntityDict> {
} else { } else {
isSuccess = response.status === 200 || response.status === 204; isSuccess = response.status === 200 || response.status === 204;
} }
if (isSuccess) { if (isSuccess) {
return; return;
} }
@ -83,17 +87,22 @@ export default class S3 implements Cos<EntityDict> {
} }
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string,
},
) { ) {
const { application, extraFile, style } = options;
const { config: s3CosConfig, endpoint } = this.getConfig(application); const { config: s3CosConfig, endpoint } = this.getConfig(application);
if (s3CosConfig) { if (s3CosConfig) {
let bucket = ( let bucket = (
s3CosConfig.buckets as S3CosConfig['buckets'] s3CosConfig.buckets as S3CosConfig['buckets']
).find((ele) => ele.name === extraFile.bucket!); ).find((ele) => ele.name === extraFile.bucket!);
if (bucket) { if (bucket) {
const { domain, protocol, pathStyle } = bucket; const { domain, protocol, pathStyle } = bucket;
let protocol2 = protocol; let protocol2 = protocol;
@ -103,14 +112,14 @@ export default class S3 implements Cos<EntityDict> {
: 0; : 0;
protocol2 = protocol[index]; protocol2 = protocol[index];
} }
const key = this.formKey(extraFile); const key = this.formKey(extraFile);
// 如果使用 pathStyle (Minio 常用) // 如果使用 pathStyle (Minio 常用)
if (pathStyle && endpoint) { if (pathStyle && endpoint) {
return `${protocol2}//${domain}/${bucket.name}/${key}${style ? style : ''}`; return `${protocol2}//${domain}/${bucket.name}/${key}${style ? style : ''}`;
} }
// 否则使用虚拟主机风格 (AWS S3 默认) // 否则使用虚拟主机风格 (AWS S3 默认)
return `${protocol2}//${domain}/${key}${style ? style : ''}`; return `${protocol2}//${domain}/${key}${style ? style : ''}`;
} }

View File

@ -4,7 +4,7 @@ import { CosBackend } from '../../types/Cos';
import TencentYun from './tencent'; import TencentYun from './tencent';
import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema'; import { OpSchema } from '../../oak-app-domain/ExtraFile/Schema';
import { TencentYunCosConfig } from '../../types/Config'; import { Protocol, TencentYunCosConfig } from '../../types/Config';
import { TencentYunInstance, TencentYunSDK } from 'oak-external-sdk'; import { TencentYunInstance, TencentYunSDK } from 'oak-external-sdk';
import { OakExternalException } from 'oak-domain/lib/types/Exception'; import { OakExternalException } from 'oak-domain/lib/types/Exception';
import { BRC } from '../..'; import { BRC } from '../..';
@ -25,12 +25,34 @@ export default class TencentYunBackend extends TencentYun implements CosBackend<
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
extraFile: OpSchema, application: EntityDict['application']['Schema'],
context: BRC<EntityDict>, extraFile: OpSchema,
style?: string context: BRC<EntityDict>,
style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
const { config: tencentCosConfig } = this.getConfig(application);
if (tencentCosConfig) {
let bucket = (
tencentCosConfig.buckets as TencentYunCosConfig['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 Protocol[]).includes('https:')
? protocol.findIndex((ele) => ele === 'https:')
: 0;
protocol2 = protocol[index];
}
return `${protocol2}//${domain}/${this.formKey(extraFile)}${style ? style : ''}`;
}
}
return '';
} }
async formUploadMeta( async formUploadMeta(

View File

@ -40,12 +40,16 @@ export default class TencentYun implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
const uploadMeta = extraFile.uploadMeta! as TencentYunUploadInfo; const uploadMeta = extraFile.uploadMeta! as TencentYunUploadInfo;
let response; let response;
try { try {
@ -89,10 +93,14 @@ export default class TencentYun implements Cos<EntityDict> {
} }
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string
}
) { ) {
const { application, extraFile, style } = options;
const { config: tencentCosConfig } = this.getConfig(application); const { config: tencentCosConfig } = this.getConfig(application);
if (tencentCosConfig) { if (tencentCosConfig) {

View File

@ -14,12 +14,15 @@ export default class UnknownBackend extends Unknown implements CosBackend<Entity
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
application: EntityDict['application']['Schema'],
extraFile: OpSchema, extraFile: OpSchema,
context: BRC<EntityDict>, context: BRC<EntityDict>,
style?: string style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
return extraFile.extra1!;
} }
async formUploadMeta( async formUploadMeta(

View File

@ -25,21 +25,27 @@ export default class Unknown implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
throw new OakUploadException('unknown未实现上传'); throw new OakUploadException('unknown未实现上传');
} }
// 类型unknown 只能从extra1取值 // 类型unknown 只能从extra1取值
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string //多媒体样式 extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string //多媒体样式
}
) { ) {
const { application, extraFile, style } = options;
return extraFile.extra1!; return extraFile.extra1!;
} }
} }

View File

@ -21,12 +21,15 @@ export default class WechatBackend extends Wechat implements CosBackend<EntityDi
} }
async composeFileUrlBackend( async composeFileUrlBackend(
application: EntityDict['application']['Schema'], options: {
extraFile: OpSchema, application: EntityDict['application']['Schema'],
context: BRC<EntityDict>, extraFile: OpSchema,
style?: string context: BRC<EntityDict>,
style?: string
}
) { ) {
return this.composeFileUrl(application, extraFile, style) const { application, extraFile, context, style } = options;
return ''
} }
async formUploadMeta( async formUploadMeta(

View File

@ -32,12 +32,17 @@ export default class Wechat implements Cos<EntityDict> {
} }
async upload( async upload(
extraFile: OpSchema, options: {
uploadFn: UploadFn, extraFile: OpSchema,
file: string | File, uploadFn: UploadFn,
uploadToAspect?: UploadToAspect, file: string | File,
getPercent?: Function uploadToAspect?: UploadToAspect,
getPercent?: Function
}
) { ) {
const { extraFile, uploadFn, file, uploadToAspect, getPercent } = options;
let result: response; let result: response;
const { applicationId, type, extra2, id } = extraFile; const { applicationId, type, extra2, id } = extraFile;
assert(type === 'image'); assert(type === 'image');
@ -67,9 +72,11 @@ export default class Wechat implements Cos<EntityDict> {
} }
composeFileUrl( composeFileUrl(
application: Partial<EntityDict['application']['Schema']>, options: {
extraFile: Partial<EntityDict['extraFile']['OpSchema']>, application: Partial<EntityDict['application']['Schema']>,
style?: string extraFile: Partial<EntityDict['extraFile']['OpSchema']>,
style?: string
}
) { ) {
return ''; return '';
} }