166 lines
4.2 KiB
JavaScript
166 lines
4.2 KiB
JavaScript
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
|
||
};
|