174 lines
5.6 KiB
JavaScript
174 lines
5.6 KiB
JavaScript
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
let db;
|
|
|
|
function init(database) {
|
|
db = database;
|
|
}
|
|
|
|
function getImagesDir() {
|
|
const dir = path.join(__dirname, '..', '..', 'data', 'hero_images');
|
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
return dir;
|
|
}
|
|
|
|
function getVideosDir() {
|
|
const dir = path.join(__dirname, '..', '..', 'data', 'hero_videos');
|
|
if (!fs.existsSync(dir)) fs.mkdirSync(dir, { recursive: true });
|
|
return dir;
|
|
}
|
|
|
|
function getPublicHero(req, res) {
|
|
db.all(
|
|
`SELECT id, type, path, sort_order FROM hero_media WHERE is_active = 1 ORDER BY sort_order ASC, id ASC`,
|
|
[],
|
|
(err, rows) => {
|
|
if (err) {
|
|
console.error('Get hero media error:', err);
|
|
return res.status(500).json({ error: 'Database error' });
|
|
}
|
|
res.json(rows);
|
|
}
|
|
);
|
|
}
|
|
|
|
function getAdminHero(req, res) {
|
|
db.all(
|
|
`SELECT * FROM hero_media ORDER BY sort_order ASC, id ASC`,
|
|
[],
|
|
(err, rows) => {
|
|
if (err) {
|
|
console.error('Get admin hero media error:', err);
|
|
return res.status(500).json({ error: 'Database error' });
|
|
}
|
|
rows.forEach(row => {
|
|
row.created_at = row.created_at ? new Date(row.created_at).toISOString() : null;
|
|
});
|
|
res.json(rows);
|
|
}
|
|
);
|
|
}
|
|
|
|
function createHeroMedia(req, res) {
|
|
const { type, path: mediaPath, sort_order } = req.body;
|
|
|
|
if (!type || !mediaPath) {
|
|
return res.status(400).json({ error: 'Type and path are required' });
|
|
}
|
|
if (!['image', 'video'].includes(type)) {
|
|
return res.status(400).json({ error: 'Type must be "image" or "video"' });
|
|
}
|
|
|
|
db.run(
|
|
`INSERT INTO hero_media (type, path, sort_order, is_active) VALUES (?, ?, ?, 1)`,
|
|
[type, mediaPath, sort_order || 0],
|
|
function(err) {
|
|
if (err) {
|
|
console.error('Create hero media error:', err);
|
|
return res.status(500).json({ error: 'Database error' });
|
|
}
|
|
res.status(201).json({ message: 'Hero media created', id: this.lastID });
|
|
}
|
|
);
|
|
}
|
|
|
|
function updateHeroMedia(req, res) {
|
|
const id = parseInt(req.params.id);
|
|
const allowed = ['type', 'path', 'sort_order', 'is_active'];
|
|
const fields = [];
|
|
const values = [];
|
|
|
|
allowed.forEach(f => {
|
|
if (req.body[f] !== undefined) {
|
|
fields.push(f + ' = ?');
|
|
values.push(req.body[f]);
|
|
}
|
|
});
|
|
|
|
if (!fields.length) {
|
|
return res.status(400).json({ error: 'No fields to update' });
|
|
}
|
|
|
|
values.push(id);
|
|
|
|
db.run(
|
|
`UPDATE hero_media SET ${fields.join(', ')} WHERE id = ?`,
|
|
values,
|
|
function(err) {
|
|
if (err) {
|
|
console.error('Update hero media error:', err);
|
|
return res.status(500).json({ error: 'Database error' });
|
|
}
|
|
if (this.changes === 0) {
|
|
return res.status(404).json({ error: 'Hero media not found' });
|
|
}
|
|
res.json({ message: 'Hero media updated', id });
|
|
}
|
|
);
|
|
}
|
|
|
|
function deleteHeroMedia(req, res) {
|
|
const id = parseInt(req.params.id);
|
|
|
|
db.get(`SELECT path FROM hero_media WHERE id = ?`, [id], (err, row) => {
|
|
if (err) {
|
|
console.error('Find hero media error:', err);
|
|
return res.status(500).json({ error: 'Database error' });
|
|
}
|
|
if (!row) {
|
|
return res.status(404).json({ error: 'Hero media not found' });
|
|
}
|
|
|
|
db.run(`DELETE FROM hero_media WHERE id = ?`, [id], function(err) {
|
|
if (err) {
|
|
console.error('Delete hero media error:', err);
|
|
return res.status(500).json({ error: 'Database error' });
|
|
}
|
|
|
|
const filePath = row.path;
|
|
if (filePath && !filePath.startsWith('http')) {
|
|
const fullPath = path.join(__dirname, '..', '..', filePath);
|
|
if (fs.existsSync(fullPath)) {
|
|
fs.unlink(fullPath, (unlinkErr) => {
|
|
if (unlinkErr) console.error('Failed to delete file:', unlinkErr);
|
|
});
|
|
}
|
|
}
|
|
|
|
res.json({ message: 'Hero media deleted', id });
|
|
});
|
|
});
|
|
}
|
|
|
|
function uploadHeroImage(req, res) {
|
|
if (!req.file) {
|
|
return res.status(400).json({ error: 'No file uploaded' });
|
|
}
|
|
const filename = req.file.filename;
|
|
const imagePath = 'data/hero_images/' + filename;
|
|
res.json({ message: 'Image uploaded', path: imagePath, filename });
|
|
}
|
|
|
|
function uploadHeroVideo(req, res) {
|
|
if (!req.file) {
|
|
return res.status(400).json({ error: 'No file uploaded' });
|
|
}
|
|
const filename = req.file.filename;
|
|
const videoPath = 'data/hero_videos/' + filename;
|
|
res.json({ message: 'Video uploaded', path: videoPath, filename });
|
|
}
|
|
|
|
function setupRoutes(app, authenticateToken, requireAdmin, uploadImage, uploadVideo) {
|
|
app.get('/api/hero', getPublicHero);
|
|
|
|
app.get('/api/admin/hero', authenticateToken, getAdminHero);
|
|
app.post('/api/admin/hero', authenticateToken, createHeroMedia);
|
|
app.put('/api/admin/hero/:id', authenticateToken, updateHeroMedia);
|
|
app.delete('/api/admin/hero/:id', authenticateToken, deleteHeroMedia);
|
|
app.post('/api/admin/hero/upload-image', authenticateToken, uploadImage.single('image'), uploadHeroImage);
|
|
app.post('/api/admin/hero/upload-video', authenticateToken, uploadVideo.single('video'), uploadHeroVideo);
|
|
}
|
|
|
|
module.exports = { init, setupRoutes, getImagesDir, getVideosDir };
|