"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getApplication = getApplication; exports.signatureJsSDK = signatureJsSDK; exports.uploadWechatMedia = uploadWechatMedia; exports.getMaterial = getMaterial; exports.deleteMaterial = deleteMaterial; exports.batchGetArticle = batchGetArticle; exports.getArticle = getArticle; exports.batchGetMaterialList = batchGetMaterialList; const tslib_1 = require("tslib"); const assert_1 = require("oak-domain/lib/utils/assert"); const Projection_1 = require("../types/Projection"); const WechatSDK_1 = tslib_1.__importDefault(require("oak-external-sdk/lib/WechatSDK")); const fs_1 = tslib_1.__importDefault(require("fs")); const lodash_1 = require("oak-domain/lib/utils/lodash"); const uuid_1 = require("oak-domain/lib/utils/uuid"); const version_1 = require("oak-domain/lib/utils/version"); const Exception_1 = require("oak-domain/lib/types/Exception"); async function getApplicationByDomain(context, options) { const { data, type, domain } = options; let applications = await context.select('application', { data, filter: { type, system: { domain$system: { url: domain, }, }, domain: { url: domain, }, }, }, {}); (0, assert_1.assert)(applications.length <= 1, `应用指定域名(domainId)只能存在一项或未指定,域名「${domain}」`); if (applications.length === 0) { applications = await context.select('application', { data: data, filter: { type, system: { domain$system: { url: domain, }, }, domainId: { $exists: false, }, }, }, {}); } return applications; } function checkAppVersionSafe(application, version) { const { dangerousVersions, warningVersions, system } = application; const { oldestVersion, platform } = system; const { oldestVersion: pfOldestVersion } = platform || {}; const oldest = pfOldestVersion || oldestVersion; if (oldest) { if ((0, version_1.compareVersion)(version, oldest) < 0) { throw new Exception_1.OakApplicationHasToUpgrade(); } } if (dangerousVersions && dangerousVersions.includes(version)) { throw new Exception_1.OakApplicationHasToUpgrade(); } (0, lodash_1.unset)(application, 'dangerousVersions'); if (warningVersions) { application.warningVersions = warningVersions.filter(ele => ele === version); } } async function getApplication(params, context) { const { type, domain, data, appId, version } = params; // 先找指定domain的应用,如果不存在再找系统下面的domain, 但无论怎么样都必须一项 const applications = await getApplicationByDomain(context, { type, domain, data, }); switch (type) { case 'wechatMp': { (0, assert_1.assert)(applications.length === 1, `微信小程序环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`); const application = applications[0]; checkAppVersionSafe(application, version); return application.id; } case 'native': { (0, assert_1.assert)(applications.length === 1, `APP环境下,同一个系统必须存在唯一的【${type}】应用,域名「${domain}」`); const application = applications[0]; checkAppVersionSafe(application, version); return application.id; } case 'wechatPublic': { // 微信公众号环境下,未配置公众号,可以使用web的application if (applications.length === 0) { const webApplications = await getApplicationByDomain(context, { type: 'web', domain, data, }); (0, assert_1.assert)(webApplications.length === 1, `微信公众号环境下, 可以未配置公众号,但必须存在web应用,域名「${domain}」`); const application = webApplications[0]; checkAppVersionSafe(application, version); return application.id; } (0, assert_1.assert)(applications.length === 1, `微信公众号环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`); const application = applications[0]; checkAppVersionSafe(application, version); return application.id; } case 'web': { (0, assert_1.assert)(applications.length === 1, `web环境下,同一个系统必须存在唯一的【${type}】应用 或 多个${type}应用必须配置域名,域名「${domain}」`); const application = applications[0]; checkAppVersionSafe(application, version); return application.id; } default: { (0, assert_1.assert)(false, `不支持的类型【${type}】,域名「${domain}」`); return; } } } async function signatureJsSDK({ url, env }, context) { const application = context.getApplication(); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic' && config.type === 'wechatPublic'); const config2 = config; const { appId, appSecret } = config2; const wechatInstance = WechatSDK_1.default.getInstance(appId, 'wechatPublic', appSecret); const result = await wechatInstance.signatureJsSDK({ url }); return result; } async function uploadWechatMedia(params, // FormData表单提交 isPermanent 变成 'true' | 'false' context) { const { applicationId, file, type: mediaType, description, extraFileId, } = params; (0, assert_1.assert)(applicationId); const isPermanent = params.isPermanent === 'true'; const filename = file.originalFilename; const filetype = file.mimetype; const fileLength = file.size; const fileStream = fs_1.default.createReadStream(file.filepath); const [application] = await context.select('application', { data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection), filter: { id: applicationId, }, }, { dontCollect: true, }); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic' || type === 'wechatMp'); let wechatInstance; if (type === 'wechatPublic') { (0, assert_1.assert)(config.type === 'wechatPublic'); const config2 = config; const { appId, appSecret } = config2; wechatInstance = WechatSDK_1.default.getInstance(appId, 'wechatPublic', appSecret); } else { (0, assert_1.assert)(config.type === 'wechatMp'); const config2 = config; const { appId, appSecret } = config2; wechatInstance = WechatSDK_1.default.getInstance(appId, 'wechatPublic', appSecret); } let mediaId; if (isPermanent) { // 只有公众号才能上传永久素材 (0, assert_1.assert)(type === 'wechatPublic'); const result = (await wechatInstance.createMaterial({ type: mediaType, media: fileStream, filename, filetype, fileLength, description: description ? JSON.parse(description) : null, })); mediaId = result.media_id; } else { const result = (await wechatInstance.createTemporaryMaterial({ type: mediaType, media: fileStream, filename, filetype, fileLength, })); mediaId = result.media_id; } if (extraFileId) { const closeRootMode = context.openRootMode(); try { await context.operate('extraFile', { id: await (0, uuid_1.generateNewIdAsync)(), action: 'update', data: { extra1: mediaId, }, filter: { id: extraFileId, }, }, {}); closeRootMode(); } catch (err) { closeRootMode(); throw err; } } return { mediaId, }; } async function getMaterial(params, context) { const { mediaId, applicationId, isPermanent = false } = params; (0, assert_1.assert)(applicationId); (0, assert_1.assert)(mediaId); const [application] = await context.select('application', { data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection), filter: { id: applicationId, }, }, { dontCollect: true, }); (0, assert_1.assert)(application); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic' || type === 'wechatMp'); let wechatInstance; if (type === 'wechatPublic') { const config2 = config; const { appId, appSecret } = config2; wechatInstance = WechatSDK_1.default.getInstance(appId, type, appSecret); } else { const config2 = config; const { appId, appSecret } = config2; wechatInstance = WechatSDK_1.default.getInstance(appId, type, appSecret); } let result; if (isPermanent) { // 只有公众号才能获取永久素材 (0, assert_1.assert)(type === 'wechatPublic'); result = await wechatInstance.getMaterial({ mediaId, }); } else { result = await wechatInstance.getTemporaryMaterial({ mediaId, }); } if (result instanceof ArrayBuffer) { return Buffer.from(result).toString('base64'); } return result; } async function deleteMaterial(params, context) { const { mediaId, applicationId } = params; (0, assert_1.assert)(applicationId); (0, assert_1.assert)(mediaId); const [application] = await context.select('application', { data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection), filter: { id: applicationId, }, }, { dontCollect: true, }); (0, assert_1.assert)(application); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic'); const config2 = config; const { appId, appSecret } = config2; const wechatInstance = WechatSDK_1.default.getInstance(appId, type, appSecret); const result = await wechatInstance.deleteMaterial({ mediaId, }); return result; } async function batchGetArticle(params, context) { const { applicationId, offset, count, noContent } = params; (0, assert_1.assert)(applicationId); const [application] = await context.select('application', { data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection), filter: { id: applicationId, }, }, { dontCollect: true, }); (0, assert_1.assert)(application); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic'); let appId, appSecret; const config2 = config; appId = config2.appId; appSecret = config2.appSecret; const wechatInstance = WechatSDK_1.default.getInstance(appId, type, appSecret); const result = await wechatInstance.batchGetArticle({ offset, count, noContent, }); return result; } async function getArticle(params, context) { const { applicationId, articleId } = params; (0, assert_1.assert)(applicationId); const [application] = await context.select('application', { data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection), filter: { id: applicationId, }, }, { dontCollect: true, }); (0, assert_1.assert)(application); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic'); let appId, appSecret; const config2 = config; appId = config2.appId; appSecret = config2.appSecret; const wechatInstance = WechatSDK_1.default.getInstance(appId, type, appSecret); const result = await wechatInstance.getArticle({ articleId, }); return result; } async function batchGetMaterialList(params, context) { const { applicationId } = params; (0, assert_1.assert)(applicationId); const [application] = await context.select('application', { data: (0, lodash_1.cloneDeep)(Projection_1.applicationProjection), filter: { id: applicationId, }, }, { dontCollect: true, }); (0, assert_1.assert)(application); const { type, config } = application; (0, assert_1.assert)(type === 'wechatPublic'); let appId, appSecret; const config2 = config; appId = config2.appId; appSecret = config2.appSecret; const wechatInstance = WechatSDK_1.default.getInstance(appId, type, appSecret); const { type: materialType, offset, count } = params; const result = await wechatInstance.batchGetMaterialList({ type: materialType, offset, count, }); return result; }