const { createCrudRoutes } = require('../database/crud'); const multer = require('multer'); const path = require('path'); const fs = require('fs'); const sharp = require('sharp'); let db; function init(database) { db = database; } function setupRoutes(app, auth) { const uploadDir = path.join(__dirname, '..', '..', 'data', 'equipment_images'); if (!fs.existsSync(uploadDir)) fs.mkdirSync(uploadDir, { recursive: true }); const storage = multer.diskStorage({ destination: uploadDir, filename: (req, file, cb) => { const ext = path.extname(file.originalname); cb(null, 'equip_' + Date.now() + '_' + Math.round(Math.random() * 1000) + ext); } }); const upload = multer({ storage, limits: { fileSize: 5 * 1024 * 1024 }, fileFilter: (req, file, cb) => { const allowed = ['.jpg', '.jpeg', '.png', '.webp', '.gif']; const ext = path.extname(file.originalname).toLowerCase(); cb(null, allowed.includes(ext)); } }); async function convertToWebp(filePath, fname) { const ext = path.extname(fname).toLowerCase(); if (ext === '.webp') return fname; try { const webpName = path.basename(fname, ext) + '.webp'; await sharp(filePath).webp({ quality: 85 }).toFile(path.join(uploadDir, webpName)); fs.unlinkSync(filePath); return webpName; } catch (e) { return fname; } } app.post('/api/admin/equipment/upload', auth.authenticateToken, auth.requireAdmin, upload.single('image'), async (req, res) => { if (!req.file) return res.status(400).json({ error: 'Файл не загружен' }); const fname = await convertToWebp(req.file.path, req.file.filename); res.json({ path: fname, url: `/data/equipment_images/${fname}` }); }); app.post('/api/admin/equipment/gallery/upload', auth.authenticateToken, auth.requireAdmin, upload.array('images', 10), async (req, res) => { if (!req.files || req.files.length === 0) return res.status(400).json({ error: 'Файлы не загружены' }); const results = []; for (const file of req.files) { const fname = await convertToWebp(file.path, file.filename); results.push({ path: fname, url: `/data/equipment_images/${fname}` }); } res.json(results); }); app.get('/api/admin/equipment/:id/gallery', auth.authenticateToken, auth.requireAdmin, (req, res) => { const id = parseInt(req.params.id); if (isNaN(id)) return res.status(400).json({ error: 'Неверный ID' }); db.all(`SELECT * FROM equipment_gallery WHERE equipment_id = ? ORDER BY sort_order`, [id], (err, rows) => { if (err) return res.status(500).json({ error: 'Ошибка БД' }); res.json(rows); }); }); app.post('/api/admin/equipment/:id/gallery', auth.authenticateToken, auth.requireAdmin, (req, res) => { const id = parseInt(req.params.id); if (isNaN(id)) return res.status(400).json({ error: 'Неверный ID' }); const { image_path, sort_order } = req.body; if (!image_path) return res.status(400).json({ error: 'Не указан путь к изображению' }); const stmt = db.prepare(`INSERT INTO equipment_gallery (equipment_id, image_path, sort_order) VALUES (?, ?, ?)`); stmt.run(id, image_path, sort_order || 0, function(err) { if (err) return res.status(500).json({ error: 'Ошибка создания' }); db.get(`SELECT * FROM equipment_gallery WHERE id = ?`, [this.lastID], (e2, row) => { if (e2) return res.status(500).json({}); res.status(201).json(row); }); }); stmt.finalize(); }); app.put('/api/admin/equipment/gallery/:imageId', auth.authenticateToken, auth.requireAdmin, (req, res) => { const imageId = parseInt(req.params.imageId); if (isNaN(imageId)) return res.status(400).json({ error: 'Неверный ID' }); const { image_path, sort_order } = req.body; const stmt = db.prepare(`UPDATE equipment_gallery SET image_path = COALESCE(?, image_path), sort_order = COALESCE(?, sort_order) WHERE id = ?`); stmt.run(image_path || null, sort_order != null ? sort_order : null, imageId, function(err) { if (err) return res.status(500).json({ error: 'Ошибка обновления' }); if (this.changes === 0) return res.status(404).json({ error: 'Не найдено' }); db.get(`SELECT * FROM equipment_gallery WHERE id = ?`, [imageId], (e2, row) => { res.json(row); }); }); stmt.finalize(); }); app.delete('/api/admin/equipment/gallery/:imageId', auth.authenticateToken, auth.requireAdmin, (req, res) => { const imageId = parseInt(req.params.imageId); if (isNaN(imageId)) return res.status(400).json({ error: 'Неверный ID' }); const stmt = db.prepare(`DELETE FROM equipment_gallery WHERE id = ?`); stmt.run(imageId, function(err) { if (err) return res.status(500).json({ error: 'Ошибка удаления' }); if (this.changes === 0) return res.status(404).json({ error: 'Не найдено' }); res.json({ message: 'Удалено' }); }); stmt.finalize(); }); createCrudRoutes(app, auth, 'equipment', { fields: ['name', 'brand', 'image_path', 'qty', 'specs', 'age_badge', 'sort_order', 'is_active'] }); } module.exports = { init, setupRoutes };