first push
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
import { Router, Request, Response } from 'express'
|
||||
import path from 'path'
|
||||
import fs from 'fs'
|
||||
import { q, Model, ModelPdf, Category } from '../db/index'
|
||||
import { geometryOutputPath } from '../services/stepConverter'
|
||||
|
||||
const UPLOADS_DIR = process.env.UPLOADS_DIR ?? path.join(process.cwd(), 'uploads')
|
||||
|
||||
const router = Router()
|
||||
|
||||
router.get('/view/:slug', (req: Request, res: Response) => {
|
||||
const model = q<Model & { category_name: string | null }>(`
|
||||
SELECT m.*, c.name AS category_name
|
||||
FROM models m
|
||||
LEFT JOIN categories c ON c.id = m.category_id
|
||||
WHERE m.slug = ?
|
||||
`).get(req.params.slug)
|
||||
|
||||
if (!model) {
|
||||
res.status(404).render('error', { status: 404, message: 'Model not found.' })
|
||||
return
|
||||
}
|
||||
|
||||
if (!model.is_public && !(req.session as { isAdmin?: boolean }).isAdmin) {
|
||||
res.status(403).render('error', { status: 403, message: 'This model is not publicly available.' })
|
||||
return
|
||||
}
|
||||
|
||||
const pdfs = q<ModelPdf>(`SELECT * FROM model_pdfs WHERE model_id = ? ORDER BY sort_order`).all(model.id)
|
||||
const baseUrl = process.env.BASE_URL ?? `http://localhost:${process.env.PORT ?? 3000}`
|
||||
|
||||
// Determine whether pre-processed geometry is available for STEP/STP
|
||||
let hasGeometry = false
|
||||
if (model.file_type === 'step' || model.file_type === 'stp') {
|
||||
const absPath = path.resolve(UPLOADS_DIR, model.file_path)
|
||||
hasGeometry = fs.existsSync(geometryOutputPath(absPath))
|
||||
}
|
||||
|
||||
res.render('viewer', {
|
||||
model,
|
||||
pdfs,
|
||||
shareUrl: `${baseUrl}/view/${model.slug}`,
|
||||
hasGeometry,
|
||||
})
|
||||
})
|
||||
|
||||
// ---- Public model index --------------------------------------------------
|
||||
|
||||
router.get('/', (_req: Request, res: Response) => {
|
||||
// Fetch categories that have at least one public model, plus their models
|
||||
const categories = q<Category & { model_count: number }>(`
|
||||
SELECT c.*, COUNT(m.id) AS model_count
|
||||
FROM categories c
|
||||
INNER JOIN models m ON m.category_id = c.id AND m.is_public = 1
|
||||
GROUP BY c.id
|
||||
HAVING model_count > 0
|
||||
ORDER BY c.sort_order, c.name
|
||||
`).all()
|
||||
|
||||
// For each category, fetch its models
|
||||
const categorised = categories.map(cat => ({
|
||||
category: cat,
|
||||
models: q<Model>(`
|
||||
SELECT * FROM models
|
||||
WHERE is_public = 1 AND category_id = ?
|
||||
ORDER BY created_at DESC
|
||||
`).all(cat.id),
|
||||
}))
|
||||
|
||||
const uncategorized = q<Model>(`
|
||||
SELECT * FROM models
|
||||
WHERE is_public = 1 AND category_id IS NULL
|
||||
ORDER BY created_at DESC
|
||||
`).all()
|
||||
|
||||
res.render('index', { categorised, uncategorized })
|
||||
})
|
||||
|
||||
export default router
|
||||
Reference in New Issue
Block a user