UNPKG

@tasolutions/express-core

Version:
169 lines (144 loc) 6.68 kB
const queryUtil = require('../../../../utils/query.util'); const Response = require('../../../../utils/response'); const { httpStatus } = require('../../../../utils/httpStatus'); const { genFile } = require('../helpers/document'); const { DocumentTemplate } = require('../models'); const { flattenObject, calculateYearDifferenceForFlattenedData, sanitizeDataForTemplate, ensureAllFieldsPresent, convertStringBooleans, addBooleanTicks } = require('../utils/document'); module.exports = { /** * Preview - Chỉ hiển thị dữ liệu đã được xử lý mà không tạo file */ preview: async (req, res, Collection) => { try { const { _id } = req.params; const documentTemplate = await DocumentTemplate.findByID(_id); if (!documentTemplate) throw { message: `Document not found with id=${_id}` }; // Xử lý dữ liệu giống như trong genFile nhưng không tạo file let dataFinal = { _id: 'example_id', ...req.body }; // Đảm bảo tất cả field schema của Collection đều có mặt dataFinal = ensureAllFieldsPresent(dataFinal, Collection); // Xử lý QR code nếu cần const qrFields = documentTemplate.qrcode_fields || []; if (qrFields.length > 0) { for (const field of qrFields) { if (dataFinal[field]) { dataFinal[`qrcode_${field}`] = `[QR Code for: ${dataFinal[field]}]`; } } } // Xử lý barcode nếu cần const barcodeFields = documentTemplate.barcode_fields || []; if (barcodeFields.length > 0) { for (const field of barcodeFields) { if (dataFinal[field]) { dataFinal[`barcode_${field}`] = `[Barcode for: ${dataFinal[field]}]`; } } } // Xử lý dữ liệu giống như trong genFile const dataRender = flattenObject(dataFinal); dataFinal = calculateYearDifferenceForFlattenedData(dataRender); // Thêm bước convert string boolean và add tick dataFinal = convertStringBooleans(dataFinal); dataFinal = addBooleanTicks(dataFinal, Collection); dataFinal = sanitizeDataForTemplate(dataFinal); return Response.success( res, { template: documentTemplate, data_template: dataFinal }, 'Preview data successfully' ); } catch (e) { console.error('Preview error:', e); return Response.error(res, e.message || 'Lỗi khi xem trước dữ liệu'); } }, /** * Review - Tạo file thực tế để xem trước */ review: async (req, res, Collection) => { try { const { _id } = req.params; const { barcode_options } = req.body; const documentTemplate = await DocumentTemplate.findByID(_id); if (!documentTemplate) throw { message: `Document not found with id=${_id}` }; const collection_name = Collection.modelName; // Lấy qrFields và barcodeFields từ template nếu có const qrFields = documentTemplate.qrcode_fields || []; const barcodeFields = documentTemplate.barcode_fields || []; const results = await genFile( documentTemplate, collection_name, ensureAllFieldsPresent({ _id: 'example_id', ...req.body }, Collection), qrFields, barcodeFields, barcode_options || {}, Collection ); return Response.success(res, results, 'Review document successfully'); } catch (e) { console.error('Review error:', e); return Response.error(res, e.message || 'Lỗi khi xem trước tài liệu'); } }, /** * Hàm sinh tài liệu hàng loạt của module này */ generate: async (req, res, Collection) => { try { const { _id } = req.params; const { barcode_options } = req.body; const documentTemplate = await DocumentTemplate.findByID(_id); if (!documentTemplate) throw { message: `Document not found with id=${_id}` }; const collection_name = Collection.modelName; const hash = req.body; let option = {}; for (const key of Object.keys(hash)) { // Bỏ qua các tùy chọn đặc biệt if (key !== 'barcode_options' && key !== 'qrcode_fields' && key !== 'barcode_fields') { option[key] = { $in: hash[key] }; } } const populate = queryUtil.populateField(Collection); const results = Object.entries(option).length ? await Collection.find(option).populate(populate) : []; const jsonResults = JSON.parse(JSON.stringify(results)); // Gọi hàm xử lý theo giới hạn (có thể sửa limit tùy ý) processWithLimit(jsonResults, 2, documentTemplate, collection_name, barcode_options, Collection); return Response.success( res, { count: jsonResults.length }, 'Đã bắt đầu quá trình tạo tài liệu hàng loạt' ); } catch (e) { console.error('Generate error:', e); return Response.error(res, e.message || 'Lỗi khi tạo tài liệu hàng loạt'); } } }; /** * Hàm xử lý tuần tự, giới hạn số lượng chạy cùng lúc (limit) */ async function processWithLimit(results, limit = 2, documentTemplate, collectionName, barcodeOptions = {}, Collection) { const queue = [...results]; while (queue.length) { const batch = queue.splice(0, limit); await Promise.all( batch.map(r => genFile( documentTemplate, collectionName, r, documentTemplate.qrcode_fields || [], documentTemplate.barcode_fields || [], barcodeOptions, Collection ).catch(err => { console.error('Lỗi trong batch:', err); }) ) ); await new Promise(res => setTimeout(res, 200)); // tránh quá tải và lỗi crash } }