@tasolutions/express-core
Version:
All libs for express
154 lines (129 loc) • 6.84 kB
JavaScript
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);
}
},
};