Archiv: Geteilt-von-mir Tab + 3D-Datei Downloads für Owner und Empfänger

This commit is contained in:
2026-05-28 13:39:33 +02:00
parent 83e88745fa
commit 2da72f1246
2 changed files with 167 additions and 25 deletions

View File

@@ -31,12 +31,81 @@ router.get('/', authenticate, (req, res) => {
ORDER BY c.created_at DESC
`).all(uid);
// Geteilt von mir
const sharedByMe = db.prepare(`
SELECT c.*, u.username as shared_with_name, cs.created_at as shared_at
FROM calculations c
JOIN calculation_shares cs ON cs.calc_id = c.id
JOIN users u ON u.id = cs.shared_with
WHERE c.user_id = ?
ORDER BY c.name ASC
`).all(uid);
// has_files auch für shared items prüfen (anhand owner's Ordner)
const sharedWithFiles = shared.map(i => {
const ownerBase = db.prepare(
"SELECT id FROM folders WHERE user_id=? AND name='3D-Modelle' AND parent_id IS NULL"
).get(i.user_id);
let has_files = false;
if (ownerBase) {
const sub = db.prepare(
'SELECT id FROM folders WHERE user_id=? AND name=? AND parent_id=?'
).get(i.user_id, i.name, ownerBase.id);
if (sub) {
const cnt = db.prepare('SELECT COUNT(*) AS c FROM files WHERE folder_id=?').get(sub.id);
has_files = cnt.c > 0;
}
}
return { ...i, has_files };
});
res.json({
own: items.map(i => ({ ...i, has_files: !!filesMap[i.name] })),
shared: shared,
own: items.map(i => ({ ...i, has_files: !!filesMap[i.name] })),
shared: sharedWithFiles,
sharedByMe: sharedByMe.map(i => ({ ...i, has_files: !!filesMap[i.name] })),
});
});
// Dateien eines Modells abrufen (für Owner + shared users)
router.get('/:id/files', authenticate, (req, res) => {
const uid = req.user.id;
const calc = db.prepare('SELECT * FROM calculations WHERE id=?').get(req.params.id);
if (!calc) return res.status(404).json({ error: 'Nicht gefunden' });
const isOwner = calc.user_id === uid;
const isShared = db.prepare('SELECT id FROM calculation_shares WHERE calc_id=? AND shared_with=?').get(calc.id, uid);
if (!isOwner && !isShared) return res.status(403).json({ error: 'Kein Zugriff' });
const baseFolder = db.prepare(
"SELECT id FROM folders WHERE user_id=? AND name='3D-Modelle' AND parent_id IS NULL"
).get(calc.user_id);
if (!baseFolder) return res.json([]);
const sub = db.prepare('SELECT id FROM folders WHERE user_id=? AND name=? AND parent_id=?')
.get(calc.user_id, calc.name, baseFolder.id);
if (!sub) return res.json([]);
res.json(db.prepare('SELECT * FROM files WHERE folder_id=? ORDER BY created_at ASC').all(sub.id));
});
// Einzelne Datei herunterladen (Owner + shared users)
router.get('/:id/files/:fileId/download', authenticate, (req, res) => {
const uid = req.user.id;
const calc = db.prepare('SELECT * FROM calculations WHERE id=?').get(req.params.id);
if (!calc) return res.status(404).json({ error: 'Nicht gefunden' });
const isOwner = calc.user_id === uid;
const isShared = db.prepare('SELECT id FROM calculation_shares WHERE calc_id=? AND shared_with=?').get(calc.id, uid);
if (!isOwner && !isShared) return res.status(403).json({ error: 'Kein Zugriff' });
const file = db.prepare('SELECT * FROM files WHERE id=?').get(req.params.fileId);
if (!file) return res.status(404).json({ error: 'Datei nicht gefunden' });
const path = require('path');
const fs = require('fs');
const UPLOAD_DIR = process.env.UPLOAD_DIR || '/data/uploads';
const fp = path.join(UPLOAD_DIR, file.filename);
if (!fs.existsSync(fp)) return res.status(404).json({ error: 'Datei fehlt' });
res.download(fp, file.originalname);
});
// Share-Management
router.get('/:id/shares', authenticate, (req, res) => {
const calc = db.prepare('SELECT * FROM calculations WHERE id=? AND user_id=?').get(req.params.id, req.user.id);