auto-account-machine/src/automation-framework/core/site-adapter.js
2025-11-18 20:51:45 +08:00

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;