140 lines
6.4 KiB
JavaScript
140 lines
6.4 KiB
JavaScript
let db;
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
function init(database) {
|
|
db = database;
|
|
}
|
|
|
|
function parseRoomFields(row) {
|
|
if (!row) return null;
|
|
try { row.furniture = JSON.parse(row.furniture || '[]'); } catch { row.furniture = []; }
|
|
try { row.amenities = JSON.parse(row.amenities || '[]'); } catch { row.amenities = []; }
|
|
try { row.floors = JSON.parse(row.floors || '[]'); } catch { row.floors = []; }
|
|
return row;
|
|
}
|
|
|
|
function getAll(req, res) {
|
|
db.all(`SELECT * FROM rooms WHERE is_active = 1 ORDER BY price_per_night ASC`, [], (err, rows) => {
|
|
if (err) { console.error('Rooms API error:', err); return res.status(500).json({ error: 'Database error' }); }
|
|
rows = rows.map(parseRoomFields);
|
|
res.json(rows);
|
|
});
|
|
}
|
|
|
|
function getAllForAdmin(req, res) {
|
|
db.all(`SELECT * FROM rooms ORDER BY price_per_night ASC`, [], (err, rows) => {
|
|
if (err) { console.error('Admin rooms API error:', err); return res.status(500).json({ error: 'Database error' }); }
|
|
rows = rows.map(parseRoomFields);
|
|
res.json(rows);
|
|
});
|
|
}
|
|
|
|
function createRoom(req, res) {
|
|
const { type, name, description, rooms_count, area_sqm, max_guests, furniture, amenities, floors, price_per_night, extra_beds, extra_bed_price, is_active } = req.body;
|
|
|
|
if (!type || !name || !price_per_night) {
|
|
return res.status(400).json({ error: 'type, name и price_per_night обязательны' });
|
|
}
|
|
|
|
db.run(`INSERT INTO rooms (type, name, description, rooms_count, area_sqm, max_guests, furniture, amenities, floors, price_per_night, extra_beds, extra_bed_price, is_active) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
[type, name, description || '', rooms_count || 1, area_sqm || 20, max_guests || 2, JSON.stringify(furniture || []), JSON.stringify(amenities || []), JSON.stringify(floors || []), price_per_night, extra_beds || 0, extra_bed_price || 0, is_active !== undefined ? (is_active ? 1 : 0) : 1],
|
|
function(err) {
|
|
if (err) { console.error('Create room error:', err); return res.status(500).json({ error: 'Database error' }); }
|
|
db.get(`SELECT * FROM rooms WHERE id = ?`, [this.lastID], (err, row) => {
|
|
if (err) return res.status(500).json({ error: 'Database error' });
|
|
res.status(201).json(parseRoomFields(row));
|
|
});
|
|
}
|
|
);
|
|
}
|
|
|
|
function updateRoom(req, res) {
|
|
const { id } = req.params;
|
|
const { type, name, description, rooms_count, area_sqm, max_guests, furniture, amenities, floors, price_per_night, image_path, extra_beds, extra_bed_price, is_active } = req.body;
|
|
|
|
db.get(`SELECT * FROM rooms WHERE id = ?`, [id], (err, row) => {
|
|
if (err) return res.status(500).json({ error: 'Database error' });
|
|
if (!row) return res.status(404).json({ error: 'Номер не найден' });
|
|
|
|
db.run(`UPDATE rooms SET type = ?, name = ?, description = ?, rooms_count = ?, area_sqm = ?, max_guests = ?, furniture = ?, amenities = ?, floors = ?, price_per_night = ?, image_path = ?, extra_beds = ?, extra_bed_price = ?, is_active = ? WHERE id = ?`,
|
|
[
|
|
type ?? row.type,
|
|
name ?? row.name,
|
|
description ?? row.description,
|
|
rooms_count ?? row.rooms_count,
|
|
area_sqm ?? row.area_sqm,
|
|
max_guests ?? row.max_guests,
|
|
furniture ? JSON.stringify(furniture) : row.furniture,
|
|
amenities ? JSON.stringify(amenities) : row.amenities,
|
|
floors ? JSON.stringify(floors) : row.floors,
|
|
price_per_night ?? row.price_per_night,
|
|
image_path !== undefined ? image_path : row.image_path,
|
|
extra_beds ?? row.extra_beds,
|
|
extra_bed_price ?? row.extra_bed_price,
|
|
is_active !== undefined ? (is_active ? 1 : 0) : row.is_active,
|
|
id
|
|
],
|
|
function(err) {
|
|
if (err) { console.error('Update room error:', err); return res.status(500).json({ error: 'Database error' }); }
|
|
db.get(`SELECT * FROM rooms WHERE id = ?`, [id], (err, row) => {
|
|
if (err) return res.status(500).json({ error: 'Database error' });
|
|
res.json(parseRoomFields(row));
|
|
});
|
|
}
|
|
);
|
|
});
|
|
}
|
|
|
|
function deleteRoom(req, res) {
|
|
const { id } = req.params;
|
|
|
|
db.get(`SELECT * FROM rooms WHERE id = ?`, [id], (err, row) => {
|
|
if (err) return res.status(500).json({ error: 'Database error' });
|
|
if (!row) return res.status(404).json({ error: 'Номер не найден' });
|
|
|
|
db.run(`UPDATE rooms SET is_active = 0 WHERE id = ?`, [id], function(err) {
|
|
if (err) { console.error('Delete room error:', err); return res.status(500).json({ error: 'Database error' }); }
|
|
res.json({ message: 'Номер удалён' });
|
|
});
|
|
});
|
|
}
|
|
|
|
function uploadRoomImage(req, res) {
|
|
if (!req.file) {
|
|
return res.status(400).json({ error: 'Файл не загружен' });
|
|
}
|
|
|
|
let imagePath = 'uploads/rooms/' + req.file.filename;
|
|
|
|
if (req.file.mimetype !== 'image/webp') {
|
|
const inputPath = req.file.path;
|
|
const outputPath = path.join(path.dirname(inputPath), req.file.filename.replace(/\.[^.]+$/, '.webp'));
|
|
|
|
require('sharp')(inputPath)
|
|
.webp({ quality: 85 })
|
|
.toFile(outputPath)
|
|
.then(() => {
|
|
try { fs.unlinkSync(inputPath); } catch {}
|
|
imagePath = 'uploads/rooms/' + path.basename(outputPath);
|
|
res.json({ path: imagePath });
|
|
})
|
|
.catch(err => {
|
|
console.error('Image conversion error:', err);
|
|
res.json({ path: imagePath });
|
|
});
|
|
} else {
|
|
res.json({ path: imagePath });
|
|
}
|
|
}
|
|
|
|
function setupRoutes(app, authenticateToken, requireAdmin, upload) {
|
|
app.get('/api/rooms', getAll);
|
|
app.get('/api/admin/rooms', authenticateToken, requireAdmin, getAllForAdmin);
|
|
app.post('/api/admin/rooms', authenticateToken, requireAdmin, createRoom);
|
|
app.put('/api/admin/rooms/:id', authenticateToken, requireAdmin, updateRoom);
|
|
app.delete('/api/admin/rooms/:id', authenticateToken, requireAdmin, deleteRoom);
|
|
app.post('/api/admin/rooms/upload', authenticateToken, requireAdmin, upload.single('image'), uploadRoomImage);
|
|
}
|
|
|
|
module.exports = { init, setupRoutes }; |