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

130 lines
4.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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} 存在未上传完成的分片,无法合并`);
// 赋值顺带删除一些无用信息减小体积出现过mysql排序超出限制的问题
extrafile.chunkInfo.parts = parts.map((part, index) => ({
...extrafile.chunkInfo.parts[index],
partNumber: part.partNumber,
etag: part.etag,
uploadUrl: '', // 不需要保存上传链接
}));
await cos.mergeChunkedUpload(extrafile.application, extrafile, context);
// 更新chunkInfo状态
const closeRootMode = context.openRootMode();
try {
await context.operate('extraFile', {
id: await generateNewIdAsync(),
action: 'update',
data: {
chunkInfo: {
...extrafile.chunkInfo,
merged: true,
},
},
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);
}