oak-general-business/es/aspects/extraFile.js

149 lines
5.2 KiB
JavaScript

import WechatSDK from 'oak-external-sdk/lib/WechatSDK';
import { generateNewIdAsync } from 'oak-domain/lib/utils/uuid';
import fs from 'fs';
import { assert } from 'oak-domain/lib/utils/assert';
import { cloneDeep } from 'oak-domain/lib/utils/lodash';
import { applicationProjection, extraFileProjection } from '../types/Projection';
import { getCosBackend } from '../utils/cos/index.backend';
// 请求链接获取标题,发布时间,图片等信息
export async function getInfoByUrl(params) {
const { url } = params;
return await WechatSDK.analyzePublicArticle(url);
}
export async function uploadExtraFile(params, // FormData表单提交
context) {
const { applicationId, file, extraFileId, } = params;
assert(applicationId);
const filename = file.originalFilename;
const filetype = file.mimetype;
const fileLength = file.size;
const fileStream = fs.createReadStream(file.filepath);
const [application] = await context.select('application', {
data: cloneDeep(applicationProjection),
filter: {
id: applicationId,
},
}, {
dontCollect: true,
});
const { type, config } = application;
// 保存文件
if (extraFileId) {
const closeRootMode = context.openRootMode();
try {
await context.operate('extraFile', {
id: await generateNewIdAsync(),
action: 'update',
data: {},
filter: {
id: extraFileId,
},
}, {});
closeRootMode();
}
catch (err) {
closeRootMode();
throw err;
}
}
return {
success: true,
};
}
/**
* 合并分片上传的文件
*/
export async function mergeChunkedUpload(params, context) {
const { extraFileId } = params;
assert(extraFileId, 'extraFileId不能为空');
const [extrafile] = await context.select('extraFile', {
data: {
...extraFileProjection,
application: {
...applicationProjection,
},
enableChunkedUpload: 1,
chunkInfo: 1,
},
filter: {
id: extraFileId,
}
}, { dontCollect: true });
assert(extrafile, `找不到id为${extraFileId}的extraFile记录`);
assert(extrafile.enableChunkedUpload, `extraFile ${extraFileId} 未启用分片上传功能`);
assert(extrafile.chunkInfo, `extraFile ${extraFileId} 的chunkInfo信息缺失`);
assert(!extrafile.chunkInfo.merged, `extraFile ${extraFileId} 已经合并过分片,无需重复合并`);
// 必须保证所有分片都有上传完成
const cos = getCosBackend(extrafile.origin);
const { parts } = await cos.listMultipartUploads(extrafile.application, extrafile, context);
const allPartsDone = parts.every(part => part.etag && part.size > 0);
assert(allPartsDone, `extraFile ${extraFileId} 存在未上传完成的分片,无法合并`);
await cos.mergeChunkedUpload(extrafile.application, extrafile, parts.map(part => ({
partNumber: part.partNumber,
etag: part.etag,
})), context);
// 更新chunkInfo状态
const closeRootMode = context.openRootMode();
try {
await context.operate('extraFile', {
id: await generateNewIdAsync(),
action: 'update',
data: {
chunkInfo: {
...extrafile.chunkInfo,
merged: true,
parts: parts.map(part => part.etag),
},
},
filter: {
id: extraFileId,
},
}, {});
closeRootMode();
}
catch (err) {
closeRootMode();
throw err;
}
}
export async function presignFile(params, context) {
const { extraFileId, method = 'GET' } = params;
assert(extraFileId, 'extraFileId不能为空');
const [extrafile] = await context.select('extraFile', {
data: {
...extraFileProjection,
application: {
...applicationProjection,
},
},
filter: {
id: extraFileId,
}
}, { dontCollect: true });
assert(extrafile, `找不到id为${extraFileId}的extraFile记录`);
const cos = getCosBackend(extrafile.origin);
return await cos.presignFile(method, extrafile.application, extrafile, context);
}
export async function presignMultiPartUpload(params, context) {
const { extraFileId, from, to } = params;
assert(extraFileId, 'extraFileId不能为空');
assert(from >= 1, 'from必须大于等于1');
assert(to >= from, 'to必须大于等于from');
const [extrafile] = await context.select('extraFile', {
data: {
...extraFileProjection,
application: {
...applicationProjection,
},
chunkInfo: 1,
enableChunkedUpload: 1,
},
filter: {
id: extraFileId,
}
}, { dontCollect: true });
assert(extrafile, `找不到id为${extraFileId}的extraFile记录`);
const cos = getCosBackend(extrafile.origin);
return cos.presignMultiPartUpload(extrafile.application, extrafile, from, to, context);
}