salix/print/lib/reportEngine.js

122 lines
3.5 KiB
JavaScript
Raw Normal View History

2019-01-22 08:55:35 +00:00
const Vue = require('vue');
const VueI18n = require('vue-i18n');
const renderer = require('vue-server-renderer').createRenderer();
const fs = require('fs-extra');
// const pdf = require('phantom-html2pdf');
const pdf = require('html-pdf');
2019-01-22 08:55:35 +00:00
const juice = require('juice');
Vue.use(VueI18n);
if (!process.env.OPENSSL_CONF)
process.env.OPENSSL_CONF = '/etc/ssl/';
module.exports = {
2019-01-25 14:08:11 +00:00
path: `${appPath}/report`,
2019-01-22 08:55:35 +00:00
/**
* Renders a report component
*
* @param {String} name - Report name
* @param {Object} ctx - Request context
*/
async render(name, ctx) {
const component = require(`${this.path}/${name}`);
2019-01-25 14:08:11 +00:00
const result = await this.preFetch(component, ctx);
2019-01-22 08:55:35 +00:00
const i18n = new VueI18n({
locale: 'es',
fallbackLocale: 'es',
silentTranslationWarn: true
2019-01-22 08:55:35 +00:00
});
2019-01-25 14:08:11 +00:00
const app = new Vue({i18n,
render: h => h(result.component)});
2019-01-22 08:55:35 +00:00
return renderer.renderToString(app);
},
/**
* Prefetch all component data from asyncData method
*
2019-01-25 14:08:11 +00:00
* @param {Object} orgComponent - Component object
2019-01-22 08:55:35 +00:00
* @param {Object} ctx - Request context
*/
2019-01-25 14:08:11 +00:00
async preFetch(orgComponent, ctx) {
let component = Object.create(orgComponent);
2019-01-23 08:33:58 +00:00
let mergedData = {};
let asyncData = {};
2019-01-22 08:55:35 +00:00
let data = {};
let params = {};
2019-01-22 08:55:35 +00:00
2019-01-23 08:33:58 +00:00
if (Object.keys(ctx.body).length > 0)
params = ctx.body;
if (Object.keys(ctx.query).length > 0)
params = ctx.query;
2019-01-22 08:55:35 +00:00
await this.attachAssets(component);
2019-01-25 14:08:11 +00:00
if (orgComponent.hasOwnProperty('data'))
data = orgComponent.data();
2019-01-22 08:55:35 +00:00
2019-01-25 14:08:11 +00:00
if (orgComponent.hasOwnProperty('asyncData'))
asyncData = await orgComponent.asyncData(ctx, params);
2019-01-23 08:33:58 +00:00
mergedData = Object.assign(mergedData, data, asyncData);
2019-01-22 08:55:35 +00:00
2019-01-23 08:33:58 +00:00
component.data = function data() {
return mergedData;
};
2019-01-22 08:55:35 +00:00
2019-01-25 14:08:11 +00:00
const components = orgComponent.components;
if (components) {
2019-01-22 08:55:35 +00:00
const promises = [];
2019-01-25 14:08:11 +00:00
const childNames = [];
component.components = {};
2019-01-22 08:55:35 +00:00
2019-01-25 14:08:11 +00:00
Object.keys(components).forEach(childName => {
childNames.push(childName);
promises.push(this.preFetch(components[childName], ctx));
2019-01-22 08:55:35 +00:00
});
2019-01-25 14:08:11 +00:00
await Promise.all(promises).then(results => {
results.forEach((result, i) => {
component.components[childNames[i]] = result.component;
});
});
2019-01-22 08:55:35 +00:00
}
2019-01-25 14:08:11 +00:00
return {component};
2019-01-22 08:55:35 +00:00
},
async attachAssets(component) {
const localePath = `${this.path}/${component.name}/locale`;
2019-01-22 08:55:35 +00:00
const templatePath = `${this.path}/${component.name}/index.html`;
const stylePath = `${this.path}/${component.name}/assets/css/index`;
2019-01-22 08:55:35 +00:00
const template = await fs.readFile(templatePath, 'utf8');
const css = require(stylePath);
const cssOptions = {inlinePseudoElements: true};
2019-01-22 08:55:35 +00:00
component.i18n = require(localePath);
component.template = juice.inlineContent(template, css, cssOptions);
2019-01-22 08:55:35 +00:00
},
async toPdf(name, ctx) {
const html = await this.render(name, ctx);
2019-01-22 08:55:35 +00:00
const options = {
format: 'A4',
border: '1.5cm',
footer: {
2019-02-20 07:57:51 +00:00
height: '55px',
}
2019-01-22 08:55:35 +00:00
};
return new Promise(resolve => {
pdf.create(html, options).toStream((err, stream) => {
resolve(stream);
});
});
2019-01-22 08:55:35 +00:00
},
};