Spaces:
Running
Running
import express from 'express'; | |
import persistentImageLinkService from '../services/persistentImageLinkService.js'; | |
import { authenticateToken } from '../middleware/auth.js'; | |
const router = express.Router(); | |
/** | |
* 生成PPT所有页面的持久化链接 | |
* POST /api/persistent-links/generate-all | |
*/ | |
router.post('/generate-all', authenticateToken, async (req, res, next) => { | |
try { | |
const { pptId, slides, options = {} } = req.body; | |
const userId = req.user.userId; | |
console.log(`🔗 Generate all persistent links: userId=${userId}, pptId=${pptId}, slides=${slides?.length}`); | |
// 验证参数 | |
if (!pptId) { | |
return res.status(400).json({ error: 'PPT ID is required' }); | |
} | |
if (!slides || !Array.isArray(slides) || slides.length === 0) { | |
return res.status(400).json({ error: 'Slides data is required' }); | |
} | |
// 使用持久化链接服务批量生成链接 | |
const results = await persistentImageLinkService.updateAllPersistentLinksWithFrontendExport( | |
userId, | |
pptId, | |
slides, | |
{ | |
format: 'jpg', | |
quality: 0.9, | |
viewportSize: 1000, | |
viewportRatio: 0.5625, | |
...options | |
} | |
); | |
// 统计成功和失败的数量 | |
const successCount = results.filter(r => r.success).length; | |
const failureCount = results.filter(r => !r.success).length; | |
console.log(`✅ Persistent links generation completed: ${successCount} success, ${failureCount} failed`); | |
// 返回结果 | |
res.json({ | |
success: true, | |
message: `成功生成 ${successCount} 个持久化链接${failureCount > 0 ? `,${failureCount} 个失败` : ''}`, | |
links: results.filter(r => r.success).map(r => ({ | |
linkId: r.linkId, | |
url: r.url, | |
publicUrl: r.publicUrl, | |
pageIndex: r.pageIndex | |
})), | |
stats: { | |
total: slides.length, | |
success: successCount, | |
failure: failureCount | |
}, | |
errors: results.filter(r => !r.success).map(r => ({ | |
pageIndex: r.pageIndex, | |
error: r.error | |
})) | |
}); | |
} catch (error) { | |
console.error('Generate all persistent links failed:', error); | |
next(error); | |
} | |
}); | |
/** | |
* 获取PPT的所有持久化链接 | |
* GET /api/persistent-links/:pptId | |
*/ | |
router.get('/:pptId', authenticateToken, async (req, res, next) => { | |
try { | |
const { pptId } = req.params; | |
const userId = req.user.userId; | |
console.log(`🔍 Get persistent links: userId=${userId}, pptId=${pptId}`); | |
// 获取用户的所有持久化链接 | |
const userLinks = await persistentImageLinkService.getUserLinks(userId); | |
// 过滤出指定PPT的链接 | |
const pptLinks = userLinks.filter(link => link.pptId === pptId); | |
// 按页面索引排序 | |
pptLinks.sort((a, b) => a.pageIndex - b.pageIndex); | |
res.json({ | |
success: true, | |
links: pptLinks.map(link => ({ | |
linkId: link.linkId, | |
url: link.url, | |
publicUrl: link.publicUrl, | |
pageIndex: link.pageIndex, | |
lastUpdated: link.lastUpdated, | |
hasImage: link.hasImage, | |
imageSize: link.imageSize, | |
format: link.format | |
})) | |
}); | |
} catch (error) { | |
console.error('Get persistent links failed:', error); | |
next(error); | |
} | |
}); | |
/** | |
* 更新单个页面的持久化链接 | |
* POST /api/persistent-links/:pptId/:pageIndex/update | |
*/ | |
router.post('/:pptId/:pageIndex/update', authenticateToken, async (req, res, next) => { | |
try { | |
const { pptId, pageIndex } = req.params; | |
const { slideData, options = {} } = req.body; | |
const userId = req.user.userId; | |
console.log(`🔄 Update persistent link: userId=${userId}, pptId=${pptId}, pageIndex=${pageIndex}`); | |
// 验证参数 | |
if (!slideData) { | |
return res.status(400).json({ error: 'Slide data is required' }); | |
} | |
const pageIdx = parseInt(pageIndex); | |
if (isNaN(pageIdx) || pageIdx < 0) { | |
return res.status(400).json({ error: 'Invalid page index' }); | |
} | |
// 获取或创建持久化链接 | |
const result = await persistentImageLinkService.getOrCreatePersistentLink( | |
userId, | |
pptId, | |
pageIdx, | |
slideData, | |
{ | |
format: 'jpg', | |
quality: 0.9, | |
viewportSize: 1000, | |
viewportRatio: 0.5625, | |
...options | |
} | |
); | |
console.log(`✅ Persistent link updated: ${result.linkId}`); | |
res.json({ | |
success: true, | |
linkId: result.linkId, | |
url: result.url, | |
publicUrl: result.publicUrl, | |
pageIndex: pageIdx | |
}); | |
} catch (error) { | |
console.error('Update persistent link failed:', error); | |
next(error); | |
} | |
}); | |
/** | |
* 删除持久化链接 | |
* DELETE /api/persistent-links/:linkId | |
*/ | |
router.delete('/:linkId', authenticateToken, async (req, res, next) => { | |
try { | |
const { linkId } = req.params; | |
const userId = req.user.userId; | |
console.log(`🗑️ Delete persistent link: userId=${userId}, linkId=${linkId}`); | |
// 验证链接所有权 | |
const linkInfo = await persistentImageLinkService.getPersistentImage(linkId); | |
if (!linkInfo || linkInfo.userId !== userId) { | |
return res.status(404).json({ error: 'Persistent link not found or access denied' }); | |
} | |
// 删除链接 | |
await persistentImageLinkService.deletePersistentLink(linkId); | |
console.log(`✅ Persistent link deleted: ${linkId}`); | |
res.json({ | |
success: true, | |
message: 'Persistent link deleted successfully' | |
}); | |
} catch (error) { | |
console.error('Delete persistent link failed:', error); | |
next(error); | |
} | |
}); | |
/** | |
* 获取持久化链接服务统计信息 | |
* GET /api/persistent-links/stats | |
*/ | |
router.get('/stats', authenticateToken, async (req, res, next) => { | |
try { | |
const userId = req.user.userId; | |
console.log(`📊 Get persistent links stats: userId=${userId}`); | |
// 获取用户的所有链接 | |
const userLinks = await persistentImageLinkService.getUserLinks(userId); | |
// 计算统计信息 | |
const stats = { | |
totalLinks: userLinks.length, | |
linksWithImages: userLinks.filter(link => link.hasImage).length, | |
totalImageSize: userLinks.reduce((sum, link) => sum + (link.imageSize || 0), 0), | |
lastUpdated: userLinks.length > 0 ? | |
Math.max(...userLinks.map(link => new Date(link.lastUpdated || 0).getTime())) : null, | |
pptCount: new Set(userLinks.map(link => link.pptId)).size | |
}; | |
res.json({ | |
success: true, | |
stats: { | |
...stats, | |
lastUpdated: stats.lastUpdated ? new Date(stats.lastUpdated).toISOString() : null, | |
averageImageSize: stats.linksWithImages > 0 ? | |
Math.round(stats.totalImageSize / stats.linksWithImages) : 0, | |
totalImageSizeMB: Math.round(stats.totalImageSize / 1024 / 1024 * 100) / 100 | |
} | |
}); | |
} catch (error) { | |
console.error('Get persistent links stats failed:', error); | |
next(error); | |
} | |
}); | |
export default router; |