feat(assets): 优化资产预览性能并添加资源管理器连接状态提示
- 使用缩略图替代原图展示,通过 sharp 库生成缓存缩略图 - 优化资产分组逻辑,避免不必要的重计算 - 添加 WebSocket 连接状态提示到输入框 - 使用 `useCallback` 和 `useRef` 优化组件渲染性能 - 添加 AbortController 支持请求取消,防止内存泄漏 - 添加 `disconnected` 事件处理,自动重置会话状态
This commit is contained in:
@@ -76,7 +76,8 @@ assetsRouter.post('/scan', async (_req, res) => {
|
||||
manifest = JSON.parse(await fs.readFile(manifestPath, 'utf-8'));
|
||||
} catch { continue; }
|
||||
|
||||
const accountId = manifest.account?.id || '';
|
||||
const accountId = typeof manifest.account === 'string' ? manifest.account
|
||||
: manifest.account?.id || '';
|
||||
|
||||
// Scan images
|
||||
const imagesDir = path.join(outputDir, dir.name, 'images');
|
||||
@@ -131,5 +132,35 @@ assetsRouter.get('/file', (req, res) => {
|
||||
const fullPath = path.resolve(PROJECT_ROOT, filePath);
|
||||
if (!fullPath.startsWith(PROJECT_ROOT)) return res.status(403).send('Forbidden');
|
||||
if (!fss.existsSync(fullPath)) return res.status(404).send('Not found');
|
||||
// Cache static assets for 1 hour
|
||||
res.setHeader('Cache-Control', 'public, max-age=3600');
|
||||
res.sendFile(fullPath);
|
||||
});
|
||||
|
||||
// Serve resized thumbnail for images
|
||||
assetsRouter.get('/thumb', async (req, res) => {
|
||||
const filePath = req.query.path as string;
|
||||
const size = Math.min(parseInt(req.query.size as string) || 200, 400);
|
||||
if (!filePath) return res.status(400).send('Missing path');
|
||||
const fullPath = path.resolve(PROJECT_ROOT, filePath);
|
||||
if (!fullPath.startsWith(PROJECT_ROOT)) return res.status(403).send('Forbidden');
|
||||
if (!fss.existsSync(fullPath)) return res.status(404).send('Not found');
|
||||
|
||||
// For non-images, redirect to full file
|
||||
if (!/\.(jpe?g|png|webp)$/i.test(fullPath)) {
|
||||
return res.redirect(`/api/assets/file?path=${encodeURIComponent(filePath)}`);
|
||||
}
|
||||
|
||||
try {
|
||||
const sharp = (await import('sharp')).default;
|
||||
const buffer = await sharp(fullPath)
|
||||
.resize(size, size, { fit: 'cover' })
|
||||
.jpeg({ quality: 70 })
|
||||
.toBuffer();
|
||||
res.setHeader('Cache-Control', 'public, max-age=86400');
|
||||
res.setHeader('Content-Type', 'image/jpeg');
|
||||
res.send(buffer);
|
||||
} catch {
|
||||
res.sendFile(fullPath);
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user