add Files admin section: list with filters, search, student/group/date, pagination
This commit is contained in:
@@ -514,6 +514,40 @@ function isImageName(name) {
|
||||
return /\.(jpe?g|png|gif|webp|bmp|avif|svg|ico)$/i.test(name || '');
|
||||
}
|
||||
|
||||
app.get('/api/files', requireAdmin, async (req, res) => {
|
||||
const { search, student_name, group_id, date_from, date_to, limit, offset } = req.query;
|
||||
const conditions = [];
|
||||
const params = [];
|
||||
if (search) { params.push(`%${search}%`); conditions.push(`pf.name ILIKE $${params.length}`); }
|
||||
if (student_name) { params.push(student_name); conditions.push(`e.student_name = $${params.length}`); }
|
||||
if (group_id) { params.push(group_id); conditions.push(`e.group_id = $${params.length}`); }
|
||||
if (date_from) { params.push(date_from); conditions.push(`e.created_at >= $${params.length}::date`); }
|
||||
if (date_to) { params.push(date_to); conditions.push(`e.created_at < ($${params.length}::date + interval '1 day')`); }
|
||||
const where = conditions.length ? ' WHERE ' + conditions.join(' AND ') : '';
|
||||
const { rows: crows } = await pool.query(
|
||||
`SELECT count(*)::int AS n FROM project_files pf JOIN entries e ON e.id = pf.entry_id${where}`,
|
||||
params
|
||||
);
|
||||
const total = crows[0].n;
|
||||
let q = `SELECT pf.id, pf.token, pf.name, pf.path, e.student_name, e.created_at, g.name AS group_name
|
||||
FROM project_files pf
|
||||
JOIN entries e ON e.id = pf.entry_id
|
||||
JOIN groups g ON g.id = e.group_id${where}
|
||||
ORDER BY pf.id DESC`;
|
||||
const qparams = params.slice();
|
||||
const lim = parseInt(limit, 10);
|
||||
if (lim > 0) { qparams.push(lim); q += ` LIMIT $${qparams.length}`; }
|
||||
const off = parseInt(offset, 10);
|
||||
if (off > 0) { qparams.push(off); q += ` OFFSET $${qparams.length}`; }
|
||||
const { rows } = await pool.query(q, qparams);
|
||||
const files = rows.map(r => {
|
||||
let size = 0;
|
||||
try { size = fs.statSync(path.join(__dirname, r.path)).size; } catch {}
|
||||
return { id: r.id, token: r.token, name: r.name, student_name: r.student_name, group_name: r.group_name, created_at: r.created_at, size };
|
||||
});
|
||||
res.json({ files, total });
|
||||
});
|
||||
|
||||
app.get('/api/files/:token', async (req, res) => {
|
||||
const { rows } = await pool.query('SELECT path, name FROM project_files WHERE token = $1', [req.params.token]);
|
||||
if (!rows.length) return res.status(404).json({ error: 'Not found' });
|
||||
|
||||
Reference in New Issue
Block a user