UNPKG

@tasolutions/express-core

Version:
154 lines (129 loc) 6.84 kB
const Response = require('../../utils/response'); const queryUtil = require('../../utils/query.util'); const _ = require('lodash'); const { mapHeadersToQuery } = require('../../utils/requestHeader'); const { DocumentMedia } = require('../modules/document/models'); module.exports = { /** * This crud readManyPaginate */ readManyPaginate: async (req, res, Collection, configs) => { try { if (configs.is_docs_media) { req.query.collection_name = Collection.modelName; Collection = DocumentMedia; } if (configs.onlyOwner && req.userLogin && req.userLogin.userId) { req.query.user_id = req.userLogin.userId; } if (configs.onlyAdminOwner && req.userLogin && req.userLogin.userId) { req.query.admin_user_id = req.userLogin.userId; } const sort = queryUtil.getSort(req, configs.sort); let query = await queryUtil.getQuery(Collection, req); if (!configs.isFilterMerchant) delete query['merchant_id']; if (configs.query) { query = Object.assign({}, configs.query, query); }; const options = { lean: true, page: req.query.page || 1, limit: req.query.limit || 10, sort: sort, }; delete query['page']; delete query['limit']; delete req.query.limit; delete req.query.page; let andConditions = []; // Mảng để lưu điều kiện $and cho truy vấn // Thêm dịch vụ loại nếu có if (req.query.service_type) { andConditions.push({ service_type: req.query.service_type }); } // Xử lý tìm kiếm if (req.query.search) { const searchQuery = queryUtil.search(Collection, req.query.search); delete req.query.search; // Xoá search từ query // Thêm searchQuery vào mảng điều kiện andConditions.push(searchQuery); } // Kiểm tra nếu có điều kiện $and if (andConditions.length > 0) { query = { $and: andConditions }; } // Trở về các thuộc tính khác nếu có query = Object.assign(await mapHeadersToQuery(req, Collection), query); let results; if (configs.is_docs_media) { // Xử lý đặc biệt cho DocumentMedia với populate động options.populate = []; // Không sử dụng populate thông thường // Sử dụng paginate để lấy dữ liệu phân trang const paginateResult = await Collection.paginate(query, options); // Nhóm documents theo collection_name để xử lý populate hiệu quả const groupedByCollection = _.groupBy(paginateResult.docs, 'collection_name'); // Kết quả sau khi populate const populatedDocs = []; // Xử lý từng nhóm for (const [collectionName, docs] of Object.entries(groupedByCollection)) { if (!collectionName || collectionName === 'unknown_collection_name') { // Thêm vào kết quả mà không populate populatedDocs.push(...docs); continue; } try { // Lấy tất cả ref_id từ nhóm này const refIds = docs.map(doc => doc.ref_id).filter(id => id && id !== 'unknown_ref_id'); if (refIds.length > 0) { // Lấy dữ liệu từ collection tương ứng const mongoose = require('mongoose'); try { const targetModel = mongoose.model(collectionName); // Lấy dữ liệu từ collection đích const refData = await targetModel.find({ _id: { $in: refIds } }); const refDataMap = _.keyBy(refData, '_id'); // Gán dữ liệu populate vào từng document for (const doc of docs) { if (doc.ref_id && doc.ref_id !== 'unknown_ref_id' && refDataMap[doc.ref_id]) { doc.ref_data = refDataMap[doc.ref_id]; } populatedDocs.push(doc); } } catch (modelError) { console.error(`Model không tồn tại cho collection ${collectionName}:`, modelError.message); populatedDocs.push(...docs); } } else { populatedDocs.push(...docs); } } catch (err) { console.error(`Lỗi khi populate collection ${collectionName}:`, err.message); populatedDocs.push(...docs); } } // Cập nhật kết quả với dữ liệu đã populate results = { ...paginateResult, docs: populatedDocs }; // Áp dụng callback nếu có if (configs.callbackLIST) { results = configs.callbackLIST(results); } } else { // Xử lý bình thường cho các collection khác options.populate = configs.populate ? configs.populate : queryUtil.populateField(Collection); if (configs.callbackLIST) { results = await Collection.paginate(query, options).then(configs.callbackLIST); } else { results = await Collection.paginate(query, options); } } if (Array.isArray(configs.includeFields) && configs.includeFields.length > 0) { results.docs = results.docs.map(result => _.pick(result, configs.includeFields)); } return Response.success(res, results); } catch (e) { return Response.error(res, e.message); } }, };