import {fileURLToPath} from 'url'; import {dirname} from 'path'; import {getParam, upload} from './params.js'; import {randomString, jsonToHtml} from './utils.js'; import {FONT_STYLE} from './constants.js'; // 获取当前模块的目录名 const __filename = fileURLToPath(import.meta.url); const basePath = dirname(dirname(__filename)); // 项目根目录 // 延迟获取 upload_path,确保环境变量已被加载 let upload_path; /** * 健康检查接口 * @param {*} req * @param {*} res */ function statusHandler(req, res) { console.log("健康检查", new Date().getMilliseconds()); return res.status(200).json({}); } /** * 海报生成接口 * @param {*} req * @param {*} res * @param {*} browserManager * @param {*} storageManager */ async function posterHandler( req, res, browserManager, storageManager ) { // 确保在使用时获取最新的环境变量值 upload_path = process.env.UPLOAD_PATH || 'uploads'; upload_path = upload_path + '/posters' // 参数校验 if (!req.body || !req.body.webpage) { return res.status(400).json({ error: 'Missing required parameter: webpage' }); } const webpage = req.body.webpage; const device = req.body.device || 1; const width = req.body.width || 1920; const height = req.body.height || 1080; const type = req.body.type || 'png'; const encoding = req.body.encoding || 'binary'; const filename = 'poster_' + randomString(20) + '.' + type; let param = getParam(req, filename, upload_path); let base64; const page = browserManager.getTargetPage(); try { await page.setViewport({width: width, height: height, deviceScaleFactor: device, isMobile: true}) await page.goto(webpage, { timeout: 30000, waitUntil: 'networkidle0' }); await page.addStyleTag({content: FONT_STYLE}); await page.screenshot(param).then((data) => { base64 = data; }); await upload(res, encoding, base64, type, filename, storageManager, basePath, upload_path); // 状态码在主应用中处理 } catch (err) { console.error('Poster generation error:', err); return res.status(500).json({ error: 'Internal server error', message: err.toString() }); } finally { // 确保只归还有效的页面 if (page && !page.isClosed()) { browserManager.returnTargetPage(page); } } } /** * PDF下载接口 * @param {*} req * @param {*} res * @param {*} browserManager * @param {*} storageManager */ async function pdfHandler( req, res, browserManager, storageManager ) { // 确保在使用时获取最新的环境变量值 upload_path = process.env.UPLOAD_PATH || 'uploads'; upload_path = upload_path + '/pdfs' // 参数校验 if (!req.body || (!req.body.webpage && !req.body.html)) { return res.status(400).json({ error: 'Missing required parameter: webpage or html' }); } const webpage = req.body.webpage; let html = req.body.html; const filename = 'pdf_' + randomString(20) + '.pdf'; let base64; const page = browserManager.getTargetPage(); try { // 根据参数选择加载方式 if (html) { // 检查html是否为JSON格式,如果是则转换为HTML字符串 if (typeof html === 'object' && html !== null) { html = jsonToHtml(html); } // 直接使用HTML内容 await page.setContent(html, { timeout: 30000, }); } else { // 导航到网页 await page.goto(webpage, { timeout: 30000, waitUntil: 'networkidle0' }); } await page.addStyleTag({content: FONT_STYLE}); // 生成PDF await page.pdf({ format: 'A4', printBackground: true, path: `${upload_path}/${filename}` }); // 复用上传函数处理PDF文件 await upload(res, 'binary', base64, 'pdf', filename, storageManager, basePath, upload_path); } catch (err) { console.error('PDF generation error:', err); return res.status(500).json({ error: 'Internal server error', message: err.toString() }); } finally { // 确保只归还有效的页面 if (page && !page.isClosed()) { browserManager.returnTargetPage(page); } } } export { statusHandler, posterHandler, pdfHandler };