2025-07-08 16:19:05 +02:00
|
|
|
const express = require('express');
|
|
|
|
|
const { authenticate, authenticate_noerror } = require('../middleware/authenticate');
|
2025-05-15 14:27:46 +02:00
|
|
|
|
|
|
|
|
const router = express.Router();
|
2025-07-08 16:19:05 +02:00
|
|
|
const PageView = require('../models/PageView');
|
2025-05-15 14:27:46 +02:00
|
|
|
|
2025-07-10 00:43:37 +02:00
|
|
|
const multer = require('multer');
|
|
|
|
|
const XLSX = require('xlsx');
|
|
|
|
|
|
|
|
|
|
const upload = multer({ dest: 'uploads/' });
|
|
|
|
|
|
2025-07-11 12:55:30 +02:00
|
|
|
const Product = require('../models/product');
|
|
|
|
|
const Author = require('../models/author');
|
2025-07-10 00:43:37 +02:00
|
|
|
|
2025-07-11 15:03:01 +02:00
|
|
|
const tools = require('../tools/general');
|
|
|
|
|
|
2025-09-05 01:06:46 +02:00
|
|
|
const { MyPage } = require('../models/mypage');
|
|
|
|
|
const { MyElem } = require('../models/myelem');
|
|
|
|
|
|
2025-08-09 00:48:50 +02:00
|
|
|
const axios = require('axios');
|
|
|
|
|
|
2025-05-15 14:27:46 +02:00
|
|
|
router.post('/test-lungo', authenticate, (req, res) => {
|
2025-07-08 16:19:05 +02:00
|
|
|
const timeout = req.body.timeout;
|
|
|
|
|
|
|
|
|
|
console.log(`🕙 Richiesta iniziata con timeout=${timeout}`);
|
|
|
|
|
|
|
|
|
|
// Simuliamo un'elaborazione lunga
|
|
|
|
|
const durataMs = timeout - 2000;
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
console.log(`✅ Elaborazione completata di ${durataMs} ms`);
|
|
|
|
|
res.json({ ok: true, message: `✅ Richiesta completata con successo! (${durataMs})` });
|
|
|
|
|
}, durataMs);
|
|
|
|
|
|
|
|
|
|
// Verifico se la richiesta va a buon fine
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
if (!res.headersSent) {
|
|
|
|
|
res.status(500).json({ ok: false, message: "❌ Errore durante l'elaborazione della richiesta!" });
|
|
|
|
|
}
|
|
|
|
|
}, durataMs + 1000);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.post('/track-pageview', authenticate_noerror, async (req, res) => {
|
2025-07-10 00:43:37 +02:00
|
|
|
const { url, userAgent, idapp, referrer } = req.body;
|
2025-07-08 16:19:05 +02:00
|
|
|
const ip = req.ip || req.headers['x-forwarded-for'] || 'unknown';
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const pageView = new PageView({
|
|
|
|
|
url,
|
|
|
|
|
ip,
|
|
|
|
|
idapp,
|
2025-07-10 00:43:37 +02:00
|
|
|
referrer,
|
2025-07-08 16:19:05 +02:00
|
|
|
userId: req.user ? req.user._id : '',
|
|
|
|
|
username: req.user ? req.user.username : '',
|
|
|
|
|
userAgent,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
await pageView.save();
|
|
|
|
|
|
2025-11-15 19:38:55 +01:00
|
|
|
return res.status(200).json({ message: '' });
|
2025-07-08 16:19:05 +02:00
|
|
|
} catch (error) {
|
|
|
|
|
console.error('Errore nel salvataggio della visita:', error);
|
2025-11-15 19:38:55 +01:00
|
|
|
return res.status(500).json({ error: 'Impossibile registrare la visita' });
|
2025-07-08 16:19:05 +02:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.get('/pageviews/stats', authenticate_noerror, async (req, res) => {
|
|
|
|
|
const { userId, idapp, unique } = req.query;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const matchStage = { idapp };
|
|
|
|
|
if (userId) {
|
|
|
|
|
matchStage.$or = [{ userId }, { username: userId }];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Definiamo la base della pipeline
|
|
|
|
|
const basePipeline = [{ $match: matchStage }];
|
|
|
|
|
|
2025-07-08 18:01:24 +02:00
|
|
|
const today = startOfDay(new Date());
|
|
|
|
|
const weekAgo = startOfDay(subDays(new Date(), 7));
|
|
|
|
|
const monthAgo = startOfDay(subDays(new Date(), 30));
|
|
|
|
|
|
|
|
|
|
// Funzione dinamica per creare pipeline di conteggio
|
|
|
|
|
const countStage = (date) => {
|
|
|
|
|
const match = { timestamp: { $gte: date } };
|
|
|
|
|
if (!unique) {
|
|
|
|
|
return [{ $match: match }, { $count: 'count' }];
|
|
|
|
|
}
|
|
|
|
|
return [
|
|
|
|
|
{ $match: match },
|
|
|
|
|
{
|
|
|
|
|
$group: {
|
|
|
|
|
_id: {
|
|
|
|
|
url: '$url',
|
|
|
|
|
user: { $ifNull: ['$userId', '$ip'] },
|
|
|
|
|
date: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ $count: 'count' },
|
|
|
|
|
];
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// Pipeline completa
|
2025-07-08 16:19:05 +02:00
|
|
|
const timeStatsPipeline = [
|
|
|
|
|
...basePipeline,
|
|
|
|
|
{
|
|
|
|
|
$facet: {
|
2025-07-08 18:01:24 +02:00
|
|
|
total: !unique
|
|
|
|
|
? [{ $count: 'count' }]
|
|
|
|
|
: [
|
|
|
|
|
{
|
|
|
|
|
$group: {
|
|
|
|
|
_id: {
|
|
|
|
|
url: '$url',
|
|
|
|
|
user: { $ifNull: ['$userId', '$ip'] },
|
|
|
|
|
date: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ $count: 'count' },
|
|
|
|
|
],
|
|
|
|
|
today: countStage(today),
|
|
|
|
|
week: countStage(weekAgo),
|
|
|
|
|
month: countStage(monthAgo),
|
2025-07-08 16:19:05 +02:00
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
// Eseguiamo solo la parte delle statistiche temporali
|
|
|
|
|
const timeStatsResult = await PageView.aggregate(timeStatsPipeline);
|
|
|
|
|
|
|
|
|
|
// Ora costruiamo la pipeline completa per topPages (con o senza unique)
|
|
|
|
|
let topPagesPipeline = [...basePipeline];
|
|
|
|
|
|
|
|
|
|
if (unique) {
|
|
|
|
|
topPagesPipeline = [
|
|
|
|
|
...topPagesPipeline,
|
|
|
|
|
{
|
|
|
|
|
$group: {
|
|
|
|
|
_id: {
|
|
|
|
|
url: '$url',
|
|
|
|
|
userId: { $ifNull: ['$userId', '$ip'] },
|
|
|
|
|
date: {
|
|
|
|
|
$dateToString: {
|
|
|
|
|
format: '%Y-%m-%d',
|
|
|
|
|
date: '$timestamp',
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ $replaceRoot: { newRoot: '$_id' } },
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Aggiungi il group finale per contare le pagine
|
|
|
|
|
const topPagesResult = await PageView.aggregate([
|
|
|
|
|
...topPagesPipeline,
|
|
|
|
|
{
|
|
|
|
|
$group: {
|
|
|
|
|
_id: '$url',
|
|
|
|
|
count: { $sum: 1 },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
{ $sort: { count: -1 } },
|
|
|
|
|
{ $limit: 10 },
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
// Formattazione dei risultati
|
|
|
|
|
const formatCount = (arr) => (arr && arr.length > 0 ? arr[0].count || 0 : 0);
|
|
|
|
|
|
|
|
|
|
const stats = {
|
|
|
|
|
total: formatCount(timeStatsResult[0]?.total),
|
|
|
|
|
today: formatCount(timeStatsResult[0]?.today),
|
|
|
|
|
week: formatCount(timeStatsResult[0]?.week),
|
|
|
|
|
month: formatCount(timeStatsResult[0]?.month),
|
|
|
|
|
topPages: topPagesResult,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
res.json(stats);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
res.status(500).json({ error: 'Errore nel calcolo delle statistiche' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
function startOfDay(date) {
|
|
|
|
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function subDays(date, days) {
|
|
|
|
|
const newDate = new Date(date);
|
|
|
|
|
newDate.setDate(newDate.getDate() - days);
|
|
|
|
|
return newDate;
|
|
|
|
|
}
|
|
|
|
|
|
2025-09-02 16:22:31 +02:00
|
|
|
router.delete('/mypage/:id', authenticate, async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const { id } = req.params;
|
|
|
|
|
|
|
|
|
|
// Trova il record di MyPage da cancellare
|
2025-09-05 01:06:46 +02:00
|
|
|
const pageToDelete = await MyPage.findByIdAndDelete(id);
|
2025-09-02 16:22:31 +02:00
|
|
|
|
2025-09-05 01:06:46 +02:00
|
|
|
if (!pageToDelete) return res.status(404).json({ error: 'Pagina non trovata' });
|
2025-09-02 16:22:31 +02:00
|
|
|
if (!pageToDelete) {
|
|
|
|
|
return res.status(404).json({ error: 'Pagina non trovata' });
|
2025-09-05 01:06:46 +02:00
|
|
|
} else {
|
|
|
|
|
await MyElem.deleteAllFromThisPage(id);
|
2025-09-02 16:22:31 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.json({ message: `Pagina eliminata con successo: ${pageToDelete.path}` });
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
2025-09-05 01:06:46 +02:00
|
|
|
res.status(500).json({ error: "Errore durante l'eliminazione della pagina" });
|
2025-09-02 16:22:31 +02:00
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-07-08 16:19:05 +02:00
|
|
|
router.get('/pageviews/users', authenticate_noerror, async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const { idapp } = req.query;
|
|
|
|
|
|
|
|
|
|
// Trova tutte le entry con idapp e prendi userId e username
|
|
|
|
|
const usersData = await PageView.find({ idapp }, { userId: 1, username: 1, _id: 0 }).lean();
|
|
|
|
|
|
|
|
|
|
// Usa un Map per garantire unicità basata su userId
|
|
|
|
|
const uniqueUsersMap = new Map();
|
|
|
|
|
|
|
|
|
|
usersData.forEach(({ userId, username }) => {
|
|
|
|
|
if (userId && !uniqueUsersMap.has(userId)) {
|
|
|
|
|
uniqueUsersMap.set(userId, { userId, username });
|
2025-05-15 14:27:46 +02:00
|
|
|
}
|
2025-07-08 16:19:05 +02:00
|
|
|
});
|
2025-05-15 14:27:46 +02:00
|
|
|
|
2025-07-08 16:19:05 +02:00
|
|
|
// Converte la Map in array
|
|
|
|
|
const uniqueUsers = Array.from(uniqueUsersMap.values());
|
|
|
|
|
|
|
|
|
|
res.json(uniqueUsers);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
res.status(500).json({ error: 'Errore nel recupero degli utenti' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
router.get('/pageviews/weekly-top-pages', authenticate_noerror, async (req, res) => {
|
|
|
|
|
const { idapp, userId, unique, year, week } = req.query;
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
const matchStage = { idapp };
|
|
|
|
|
if (userId) {
|
|
|
|
|
matchStage.$or = [{ userId }, { username: userId }];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const pipeline = [];
|
|
|
|
|
|
|
|
|
|
// Filtro base
|
|
|
|
|
pipeline.push({ $match: matchStage });
|
2025-05-15 14:27:46 +02:00
|
|
|
|
2025-07-08 16:19:05 +02:00
|
|
|
// Estrai settimana e anno
|
|
|
|
|
pipeline.push({
|
|
|
|
|
$addFields: {
|
|
|
|
|
week: { $isoWeek: '$timestamp' },
|
|
|
|
|
year: { $isoWeekYear: '$timestamp' },
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Filtra per settimana e anno se specificati
|
|
|
|
|
if (year && week) {
|
|
|
|
|
pipeline.push({
|
|
|
|
|
$match: {
|
|
|
|
|
year: parseInt(year),
|
|
|
|
|
week: parseInt(week),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (unique === 'true') {
|
|
|
|
|
// Visite uniche: 1 per utente/giorno/pagina
|
|
|
|
|
pipeline.push({
|
|
|
|
|
$group: {
|
|
|
|
|
_id: {
|
|
|
|
|
url: '$url',
|
|
|
|
|
user: { $ifNull: ['$userId', '$ip'] },
|
|
|
|
|
day: { $dateToString: { format: '%Y-%m-%d', date: '$timestamp' } },
|
|
|
|
|
},
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Riformatta per conteggio
|
|
|
|
|
pipeline.push({
|
|
|
|
|
$group: {
|
|
|
|
|
_id: '$_id.url',
|
|
|
|
|
count: { $sum: 1 },
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
} else {
|
|
|
|
|
// Visite totali: tutte le occorrenze
|
|
|
|
|
pipeline.push({
|
|
|
|
|
$group: {
|
|
|
|
|
_id: '$url',
|
|
|
|
|
count: { $sum: 1 },
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Ordina per numero visite
|
|
|
|
|
pipeline.push({ $sort: { count: -1 } });
|
|
|
|
|
|
|
|
|
|
// Aggiungi metadati settimana/anno se presenti
|
|
|
|
|
if (year && week) {
|
|
|
|
|
pipeline.push({
|
|
|
|
|
$addFields: {
|
|
|
|
|
year: parseInt(year),
|
|
|
|
|
week: parseInt(week),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const result = await PageView.aggregate(pipeline);
|
|
|
|
|
|
|
|
|
|
res.json(
|
|
|
|
|
result.map((r) => ({
|
|
|
|
|
url: r._id,
|
|
|
|
|
count: r.count,
|
|
|
|
|
year: r.year,
|
|
|
|
|
week: r.week,
|
|
|
|
|
}))
|
|
|
|
|
);
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error(err);
|
|
|
|
|
res.status(500).json({ error: 'Errore nel calcolo delle statistiche settimanali' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-07-10 00:43:37 +02:00
|
|
|
router.post('/api/convert-csv-to-xls', upload.single('csv'), (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const csvFilePath = req.file.path;
|
2025-07-11 12:55:30 +02:00
|
|
|
|
2025-07-10 00:43:37 +02:00
|
|
|
// Leggi il CSV con SheetJS
|
|
|
|
|
const csvData = fs.readFileSync(csvFilePath, 'utf-8');
|
|
|
|
|
const worksheet = XLSX.utils.csv_to_sheet(csvData);
|
|
|
|
|
|
|
|
|
|
// Crea un file Excel
|
|
|
|
|
const workbook = XLSX.utils.book_new();
|
|
|
|
|
XLSX.utils.book_append_sheet(workbook, worksheet, 'Sheet1');
|
|
|
|
|
|
|
|
|
|
// Imposta la risposta come file XLS
|
|
|
|
|
const xlsFilePath = path.join(__dirname, 'converted', 'output.xls');
|
|
|
|
|
XLSX.writeFile(workbook, xlsFilePath);
|
|
|
|
|
|
|
|
|
|
// Restituisci il file XLS al frontend come risposta
|
|
|
|
|
res.download(xlsFilePath, 'converted-file.xls', (err) => {
|
|
|
|
|
if (err) {
|
|
|
|
|
console.error('Errore nel download del file:', err);
|
|
|
|
|
res.status(500).send('Errore nel download del file');
|
|
|
|
|
}
|
2025-07-11 12:55:30 +02:00
|
|
|
|
2025-07-10 00:43:37 +02:00
|
|
|
// Pulisci il file temporaneo
|
|
|
|
|
fs.unlinkSync(csvFilePath);
|
|
|
|
|
fs.unlinkSync(xlsFilePath);
|
|
|
|
|
});
|
|
|
|
|
} catch (error) {
|
2025-07-11 12:55:30 +02:00
|
|
|
console.error('Errore nella conversione del file:', error);
|
2025-07-10 00:43:37 +02:00
|
|
|
res.status(500).send('Errore nella conversione del file');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-07-11 15:03:01 +02:00
|
|
|
// Funzione per "escapare" i caratteri speciali
|
|
|
|
|
const escapeRegExp = (string) => {
|
|
|
|
|
return string.replace(/[.*+?^=!:${}()|\[\]\/\\]/g, '\\$&'); // Escape dei caratteri speciali
|
|
|
|
|
};
|
|
|
|
|
|
2025-07-11 12:55:30 +02:00
|
|
|
// API per la ricerca dei libri
|
|
|
|
|
router.post('/search-books', authenticate, async (req, res) => {
|
|
|
|
|
const { books } = req.body;
|
|
|
|
|
|
|
|
|
|
if (!books || books.length === 0) {
|
|
|
|
|
return res.status(400).json({ error: 'Nessun dato fornito per la ricerca' });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
// Crea un array per raccogliere i risultati
|
|
|
|
|
let results = [];
|
|
|
|
|
|
|
|
|
|
let product = null;
|
|
|
|
|
|
|
|
|
|
for (const book of books) {
|
2025-07-11 15:03:01 +02:00
|
|
|
let trovatoISBN = false;
|
|
|
|
|
let trovato = false;
|
2025-09-27 17:24:46 +02:00
|
|
|
let productfind = null;
|
|
|
|
|
|
2025-07-11 15:03:01 +02:00
|
|
|
for (let field of book) {
|
2025-09-27 17:24:46 +02:00
|
|
|
|
2025-07-11 15:03:01 +02:00
|
|
|
field = field.trim();
|
2025-07-11 12:55:30 +02:00
|
|
|
let valido = typeof field === 'string' && field.length > 4 && field.length < 50;
|
|
|
|
|
if (valido) {
|
|
|
|
|
// Cerca il primo record che corrisponde per ISBN o titolo
|
|
|
|
|
if (true) {
|
2025-07-11 15:03:01 +02:00
|
|
|
if (!trovatoISBN) {
|
2025-08-29 23:34:08 +02:00
|
|
|
let productInfoarrISBN = await Product.find({
|
|
|
|
|
'productInfo.code': field.toUpperCase(),
|
2025-07-11 15:03:01 +02:00
|
|
|
$or: [{ deleted: false }, { deleted: { $exists: false } }],
|
|
|
|
|
}).exec();
|
|
|
|
|
|
|
|
|
|
// Priorità se lo trovo per ISBN:
|
|
|
|
|
if (productInfoarrISBN.length === 1) {
|
2025-09-27 17:24:46 +02:00
|
|
|
productfind = productInfoarrISBN[0];
|
2025-07-11 15:03:01 +02:00
|
|
|
trovatoISBN = true;
|
|
|
|
|
trovato = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!trovatoISBN && !trovato) {
|
|
|
|
|
// Prima cerca se è esattamente cosi
|
2025-08-29 23:34:08 +02:00
|
|
|
let productarrTitle = await Product.find({
|
2025-07-11 15:03:01 +02:00
|
|
|
$or: [{ deleted: false }, { deleted: { $exists: false } }],
|
2025-08-29 23:34:08 +02:00
|
|
|
'productInfo.name': field,
|
2025-07-11 15:03:01 +02:00
|
|
|
}).exec();
|
2025-08-29 23:34:08 +02:00
|
|
|
if (productarrTitle.length === 1) {
|
2025-09-27 17:24:46 +02:00
|
|
|
productfind = productarrTitle[0];
|
2025-07-11 15:03:01 +02:00
|
|
|
trovato = true;
|
|
|
|
|
} else {
|
2025-08-29 23:34:08 +02:00
|
|
|
if (productarrTitle.length > 1) {
|
2025-07-11 15:03:01 +02:00
|
|
|
// Prendi l'Ultimo !
|
2025-09-27 17:24:46 +02:00
|
|
|
productfind = productarrTitle[productarrTitle.length - 1];
|
2025-07-11 15:03:01 +02:00
|
|
|
trovato = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (!trovato) {
|
|
|
|
|
// Altrimenti per Titolo
|
2025-08-29 23:34:08 +02:00
|
|
|
productarrTitle = await Product.find({
|
2025-07-11 15:03:01 +02:00
|
|
|
$or: [{ deleted: false }, { deleted: { $exists: false } }],
|
2025-08-29 23:34:08 +02:00
|
|
|
'productInfo.name': new RegExp(`.*${escapeRegExp(tools.removeAccents(field.toUpperCase()))}.*`, 'i'),
|
2025-07-11 15:03:01 +02:00
|
|
|
}).exec();
|
2025-08-29 23:34:08 +02:00
|
|
|
if (productarrTitle.length === 1) {
|
2025-09-27 17:24:46 +02:00
|
|
|
productfind = productarrTitle[0];
|
2025-07-11 15:03:01 +02:00
|
|
|
trovato = true;
|
|
|
|
|
} else {
|
2025-08-29 23:34:08 +02:00
|
|
|
if (productarrTitle.length > 1) {
|
2025-07-11 15:03:01 +02:00
|
|
|
// Prendi l'Ultimo !
|
2025-09-27 17:24:46 +02:00
|
|
|
productfind = productarrTitle[productarrTitle.length - 1];
|
2025-07-11 15:03:01 +02:00
|
|
|
trovato = true;
|
|
|
|
|
}
|
2025-07-11 12:55:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-07-11 15:03:01 +02:00
|
|
|
|
|
|
|
|
if (trovato) {
|
2025-09-27 17:24:46 +02:00
|
|
|
if (productfind) {
|
2025-11-18 13:08:53 +01:00
|
|
|
product = await Product.findOne({ _id: productfind._id }).lean().exec();
|
2025-07-11 15:03:01 +02:00
|
|
|
if (product) {
|
|
|
|
|
const existingResult = results.find((r) => r._id.toString() === product._id.toString());
|
|
|
|
|
if (!existingResult) {
|
2025-08-29 23:34:08 +02:00
|
|
|
let titolo = product.productInfo.name;
|
2025-07-11 15:03:01 +02:00
|
|
|
results.push({
|
|
|
|
|
...product,
|
|
|
|
|
_id: product._id,
|
|
|
|
|
title: titolo,
|
|
|
|
|
isbn: product.isbn,
|
|
|
|
|
authors: await Promise.all(
|
2025-08-29 23:34:08 +02:00
|
|
|
product.productInfo.idAuthors.map(async (authorId) => {
|
2025-07-11 15:03:01 +02:00
|
|
|
const author = await Author.findById(authorId).exec();
|
|
|
|
|
return author ? `${author.name} ${author.surname}`.trim() : '';
|
|
|
|
|
})
|
|
|
|
|
),
|
|
|
|
|
select: true,
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//
|
2025-07-11 12:55:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
res.status(200).json(results); // Restituisci i risultati trovati
|
|
|
|
|
} catch (err) {
|
|
|
|
|
console.error('Errore durante la ricerca dei libri:', err);
|
|
|
|
|
res.status(500).json({ error: 'Errore interno del server' });
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-08-09 00:48:50 +02:00
|
|
|
router.post('/chatbot', authenticate, async (req, res) => {
|
|
|
|
|
try {
|
|
|
|
|
const response = await axios.post('http://localhost:5005/webhooks/rest/webhook', {
|
|
|
|
|
sender: 'user',
|
|
|
|
|
message: req.body.payload.message,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
res.json(response.data);
|
|
|
|
|
} catch (error) {
|
2025-08-12 19:43:41 +02:00
|
|
|
console.error(error?.message);
|
2025-08-09 00:48:50 +02:00
|
|
|
res.status(500).send('Errore nella comunicazione con Rasa');
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
|
2025-07-08 16:19:05 +02:00
|
|
|
module.exports = router;
|