import { CreateTrigger, Trigger } from 'oak-domain/lib/types/Trigger'; import { EntityDict } from '../oak-app-domain/EntityDict'; import { getCosBackend } from '../utils/cos/index.backend'; import { OakException } from 'oak-domain/lib/types/Exception'; import { RemoveTrigger } from 'oak-domain/lib/types/Trigger'; import { BRC } from '../types/RuntimeCxt'; import { applicationProjection } from '../types/Projection'; import assert from 'assert'; import { CosOrigin } from '../types/Config'; const triggers: Trigger>[] = [ { name: '生成extraFile需要的上传meta', when: 'before', entity: 'extraFile', action: 'create', fn: async ({ operation }, context) => { const { data } = operation; let cachedOrigin: CosOrigin | undefined = undefined; const getCosOrigin = async (): Promise => { if (cachedOrigin) { return cachedOrigin; } const [application] = await context.select("application", { data: { config: { cos: { defaultOrigin: 1, } }, system: { config: { Cos: { defaultOrigin: 1, } }, platform: { config: { Cos: { defaultOrigin: 1, } } } } }, filter: { id: context.getApplicationId()!, }, }, {}); assert(application, `找不到 当前应用程序`); cachedOrigin = application.config?.cos?.defaultOrigin || application.system?.config?.Cos?.defaultOrigin || application.system?.platform?.config?.Cos?.defaultOrigin; return cachedOrigin; } const formMeta = async (data: EntityDict['extraFile']['OpSchema']): Promise => { // 如果提供了就用提供的origin,否则尝试从应用程序、系统配置、平台配置中获取默认的Cos源 const configOrigin = data.origin || await getCosOrigin(); assert(configOrigin, `extraFile的origin未指定,且应用程序、系统配置、平台配置中也没有默认的Cos源,请检查`); if (!data.applicationId) { data.applicationId = context.getApplicationId()!; } if (configOrigin === 'unknown') { Object.assign(data, { uploadState: 'success', }); return; } const cos = getCosBackend(configOrigin!); if (!cos) { throw new OakException(`origin为${configOrigin}的extraFile没有定义Cos类,请调用registerCos注入`); } await cos.formUploadMeta(context.getApplication() as EntityDict['application']['Schema'], data); Object.assign(data, { uploadState: 'uploading', }); } if (data instanceof Array) { await Promise.all( data.map(ele => formMeta(ele as EntityDict['extraFile']['OpSchema'])) ); return data.length; } await formMeta(data as EntityDict['extraFile']['OpSchema']); return 1; } } as CreateTrigger>, { name: '删除extraFile时远端也进行删除', when: 'commit', strict: 'makeSure', entity: 'extraFile', action: 'remove', fn: async ({ ids }, context) => { const fn = context.openRootMode(); const rows = await context.select('extraFile', { data: { id: 1, origin: 1, objectId: 1, bucket: 1, extension: 1, applicationId: 1, application: applicationProjection }, filter: { id: { $in: ids }, }, }, { includedDeleted: true }); for (const extraFile of rows) { const { origin, objectId, application } = extraFile; // 用objectId来去重,只有当没有还有效的objectId方可删除 const count = await context.count('extraFile', { filter: { objectId: objectId!, }, }, {}); if (count === 0) { const uploader = getCosBackend(origin!); const application2 = context.getApplication(true) || application; await uploader.removeFile( application2 as EntityDict['application']['Schema'], extraFile as EntityDict['extraFile']['OpSchema'] ); } } fn(); } } as RemoveTrigger>, ]; export default triggers;