124 lines
2.9 KiB
JavaScript
124 lines
2.9 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
const yaml = require('js-yaml');
|
|
const WorkflowEngine = require('./workflow-engine');
|
|
|
|
/**
|
|
* 站点适配器基类 - 所有网站的基类
|
|
*/
|
|
class SiteAdapter {
|
|
constructor(context, siteName) {
|
|
this.context = context;
|
|
this.siteName = siteName;
|
|
this.useConfig = true; // 默认使用配置文件
|
|
|
|
// 快捷访问
|
|
this.page = context.page;
|
|
this.logger = context.logger;
|
|
|
|
// 加载配置
|
|
if (this.useConfig) {
|
|
this.config = this.loadConfig(siteName);
|
|
this.context.siteName = this.config.site?.name || siteName;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 加载站点配置
|
|
* @param {string} siteName - 站点名称
|
|
* @returns {Object}
|
|
*/
|
|
loadConfig(siteName) {
|
|
const configPath = path.join(__dirname, '../configs/sites', `${siteName}.yaml`);
|
|
|
|
if (!fs.existsSync(configPath)) {
|
|
throw new Error(`配置文件不存在: ${configPath}`);
|
|
}
|
|
|
|
const configContent = fs.readFileSync(configPath, 'utf8');
|
|
return yaml.load(configContent);
|
|
}
|
|
|
|
/**
|
|
* 生命周期钩子 - 工作流执行前
|
|
*/
|
|
async beforeWorkflow() {
|
|
this.log('debug', '执行 beforeWorkflow 钩子');
|
|
// 子类可以重写
|
|
}
|
|
|
|
/**
|
|
* 生命周期钩子 - 工作流执行后
|
|
*/
|
|
async afterWorkflow() {
|
|
this.log('debug', '执行 afterWorkflow 钩子');
|
|
// 子类可以重写
|
|
}
|
|
|
|
/**
|
|
* 生命周期钩子 - 错误处理
|
|
* @param {Error} error - 错误对象
|
|
*/
|
|
async onError(error) {
|
|
this.log('error', `工作流执行失败: ${error.message}`);
|
|
|
|
// 截图
|
|
if (this.page) {
|
|
try {
|
|
const screenshotPath = path.join(
|
|
__dirname,
|
|
'../../logs',
|
|
`error-${Date.now()}.png`
|
|
);
|
|
await this.page.screenshot({ path: screenshotPath, fullPage: true });
|
|
this.log('info', `错误截图已保存: ${screenshotPath}`);
|
|
} catch (e) {
|
|
this.log('warn', `截图失败: ${e.message}`);
|
|
}
|
|
}
|
|
|
|
// 子类可以重写
|
|
}
|
|
|
|
/**
|
|
* 执行入口
|
|
* @returns {Promise<Object>}
|
|
*/
|
|
async execute() {
|
|
try {
|
|
// 执行前钩子
|
|
await this.beforeWorkflow();
|
|
|
|
// 创建工作流引擎
|
|
const engine = new WorkflowEngine(this.context, this.config);
|
|
this.context.engine = engine;
|
|
this.context.adapter = this;
|
|
|
|
// 执行工作流
|
|
const result = await engine.execute();
|
|
|
|
// 执行后钩子
|
|
await this.afterWorkflow();
|
|
|
|
return result;
|
|
|
|
} catch (error) {
|
|
await this.onError(error);
|
|
throw error;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 记录日志
|
|
*/
|
|
log(level, message) {
|
|
if (this.logger && this.logger[level]) {
|
|
this.logger[level](this.siteName, message);
|
|
} else {
|
|
console.log(`[${level.toUpperCase()}] ${message}`);
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = SiteAdapter;
|