исправление поиска

This commit is contained in:
2025-10-18 12:08:25 +03:00
parent 599ccd1582
commit 99127c42e2

View File

@@ -1,99 +1,94 @@
const express = require('express') const express = require('express');
const router = express.Router() const router = express.Router();
const { verifyToken } = require('../middleware/auth') const { verifyToken } = require('../middleware/auth');
const mockCompaniesData = require('../mocks/companies.json') const Company = require('../models/Company');
const mockCompanies = mockCompaniesData.mockCompanies
// Маппинг отраслей для фильтрации // GET /search - Поиск компаний (с использованием MongoDB)
const industryMapping = { router.get('/', verifyToken, async (req, res) => {
'it': 'IT',
'finance': 'Финансы',
'manufacturing': 'Производство',
'construction': 'Строительство',
'retail': 'Торговля',
'wholesale': 'Торговля',
'logistics': 'Логистика',
'healthcare': 'Медицина'
};
// GET /search/companies - Поиск компаний
router.get('/companies', verifyToken, (req, res) => {
try { try {
const { const {
query = '', query = '',
industries = '', page = 1,
companySizes = '', limit = 10,
geographies = '',
minRating = 0, minRating = 0,
hasReviews, hasReviews,
hasAccepts hasAcceptedDocs,
sortBy = 'relevance',
sortOrder = 'desc'
} = req.query; } = req.query;
let result = [...mockCompanies]; // Построение query для MongoDB
let mongoQuery = {};
// Фильтр по текстовому запросу // Текстовый поиск
if (query.trim()) { if (query && query.trim()) {
const q = query.toLowerCase(); mongoQuery.$or = [
result = result.filter(c => { fullName: { $regex: query, $options: 'i' } },
c.fullName.toLowerCase().includes(q) || { shortName: { $regex: query, $options: 'i' } },
c.shortName.toLowerCase().includes(q) || { slogan: { $regex: query, $options: 'i' } },
c.slogan.toLowerCase().includes(q) || { industry: { $regex: query, $options: 'i' } }
c.industry.toLowerCase().includes(q) ];
);
}
// Фильтр по отраслям
if (industries) {
const selectedIndustries = industries.split(',');
result = result.filter(c => {
const mappedIndustries = selectedIndustries.map(i => industryMapping[i] || i);
return mappedIndustries.some(ind =>
c.industry.toLowerCase().includes(ind.toLowerCase())
);
});
}
// Фильтр по размеру компании
if (companySizes) {
const sizes = companySizes.split(',');
result = result.filter(c => {
if (!c.companySize) return false;
return sizes.some(size => {
if (size === '1-10') return c.companySize === '1-10';
if (size === '11-50') return c.companySize === '10-50';
if (size === '51-250') return c.companySize.includes('50') || c.companySize.includes('100') || c.companySize.includes('250');
if (size === '251-500') return c.companySize.includes('250') || c.companySize.includes('500');
if (size === '500+') return c.companySize === '500+';
return false;
});
});
} }
// Фильтр по рейтингу // Фильтр по рейтингу
const rating = parseFloat(minRating); if (minRating) {
if (rating > 0) { const rating = parseFloat(minRating);
result = result.filter(c => c.rating >= rating); if (rating > 0) {
mongoQuery.rating = { $gte: rating };
}
} }
// Фильтр по наличию отзывов // Фильтр по отзывам
if (hasReviews === 'true') { if (hasReviews === 'true') {
result = result.filter(c => c.verified === true); mongoQuery.verified = true;
} }
// Фильтр по акцептам документов // Фильтр по акцептам
if (hasAccepts === 'true') { if (hasAcceptedDocs === 'true') {
result = result.filter(c => c.verified === true); mongoQuery.verified = true;
} }
// Пагинация
const pageNum = parseInt(page) || 1;
const limitNum = parseInt(limit) || 10;
const skip = (pageNum - 1) * limitNum;
// Сортировка
let sortObj = { rating: -1 };
if (sortBy === 'name') {
sortObj = { fullName: 1 };
}
if (sortOrder === 'asc') {
Object.keys(sortObj).forEach(key => {
sortObj[key] = sortObj[key] === -1 ? 1 : -1;
});
}
// Запрос к MongoDB
const companies = await Company.find(mongoQuery)
.limit(limitNum)
.skip(skip)
.sort(sortObj)
.lean();
const total = await Company.countDocuments(mongoQuery);
console.log('[Search] Returned', companies.length, 'companies');
res.json({ res.json({
companies: result, companies,
total: result.length total,
page: pageNum,
totalPages: Math.ceil(total / limitNum)
}); });
} catch (error) { } catch (error) {
console.error('Search error:', error); console.error('[Search] Error:', error.message);
res.status(500).json({ error: 'Internal server error' }); res.status(500).json({
error: 'Internal server error',
message: error.message
});
} }
}); });
module.exports = router module.exports = router;