This commit is contained in:
dengqichen 2025-11-16 23:19:40 +08:00
parent 569a5d2a0f
commit 10439f5af1

View File

@ -16,6 +16,7 @@ const CloudflareHandler = require('../utils/cloudflare-handler');
const logger = require('../../../shared/logger');
const EmailVerificationService = require('../email-verification');
const { DEFAULT_CONFIG } = require('../config');
const CardGenerator = require('../../card-generator/generator');
class WindsurfRegister {
constructor() {
@ -35,6 +36,8 @@ class WindsurfRegister {
{ id: 2, name: '设置密码', method: 'step2_setPassword' },
{ id: 3, name: '邮箱验证', method: 'step3_emailVerification' },
{ id: 4, name: '跳过问卷', method: 'step4_skipSurvey' },
{ id: 5, name: '选择计划', method: 'step5_selectPlan' },
{ id: 6, name: '填写支付信息', method: 'step6_fillPayment' },
// 根据实际注册流程继续添加
];
}
@ -471,9 +474,9 @@ class WindsurfRegister {
// 等待验证码页面加载
await this.human.readPage(1, 2);
// 延迟15秒后再获取验证码,让邮件有足够时间到达
logger.info(this.siteName, ' → 延迟15秒,等待邮件到达...');
await new Promise(resolve => setTimeout(resolve, 15000));
// 延迟2秒后再获取验证码,让邮件有足够时间到达
logger.info(this.siteName, ' → 延迟2秒,等待邮件到达...');
await new Promise(resolve => setTimeout(resolve, 2000));
// 获取验证码(从邮箱)
logger.info(this.siteName, ' → 正在从邮箱获取验证码...');
@ -609,6 +612,163 @@ class WindsurfRegister {
}
}
/**
* 步骤5: 选择计划
*/
async step5_selectPlan() {
logger.info(this.siteName, `[步骤 5/${this.getTotalSteps()}] 选择计划`);
try {
// 等待页面加载
await this.human.readPage(2, 3);
// 查找并点击"Select plan"按钮
logger.info(this.siteName, ' → 查找"Select plan"按钮...');
// 方式1: 通过按钮文本查找
const buttons = await this.page.$$('button');
let selectButton = null;
for (const button of buttons) {
const text = await this.page.evaluate(el => el.textContent?.trim(), button);
if (text && text.toLowerCase().includes('select plan')) {
selectButton = button;
logger.info(this.siteName, ` → 找到按钮: "${text}"`);
break;
}
}
if (selectButton) {
logger.info(this.siteName, ' → 点击"Select plan"按钮...');
await selectButton.click();
// 等待页面跳转或加载
await this.human.randomDelay(3000, 5000);
this.currentStep = 5;
logger.success(this.siteName, `步骤 5 完成`);
} else {
logger.warn(this.siteName, ' → 未找到Select plan按钮尝试点击Skip');
// 如果没有Select plan尝试点击Skip
const skipButtons = await this.page.$$('button');
for (const btn of skipButtons) {
const text = await this.page.evaluate(el => el.textContent?.trim(), btn);
if (text && text.toLowerCase().includes('skip')) {
await btn.click();
logger.info(this.siteName, ' → 已点击Skip按钮');
break;
}
}
await this.human.randomDelay(2000, 3000);
this.currentStep = 5;
}
} catch (error) {
logger.error(this.siteName, `选择计划失败: ${error.message}`);
throw error;
}
}
/**
* 步骤6: 填写支付信息
*/
async step6_fillPayment() {
logger.info(this.siteName, `[步骤 6/${this.getTotalSteps()}] 填写支付信息`);
try {
// 等待页面加载
await this.human.readPage(3, 5);
// 1. 生成信用卡信息(使用银联卡)
logger.info(this.siteName, ' → 生成银联卡信息...');
const cardGen = new CardGenerator();
const card = cardGen.generate('unionpay');
logger.info(this.siteName, ` → 卡号: ${card.number}`);
logger.info(this.siteName, ` → 有效期: ${card.month}/${card.year}`);
logger.info(this.siteName, ` → CVV: ${card.cvv}`);
// 2. 点击选择"银行卡"支付方式
logger.info(this.siteName, ' → 选择银行卡支付方式...');
const cardRadio = await this.page.$('input[type="radio"][value="card"]');
if (cardRadio) {
await cardRadio.click();
await this.human.randomDelay(1000, 2000);
logger.success(this.siteName, ' → ✓ 已选择银行卡');
}
// 3. 填写卡号
logger.info(this.siteName, ' → 填写卡号...');
await this.page.waitForSelector('#cardNumber', { timeout: 10000 });
await this.page.click('#cardNumber');
await this.human.randomDelay(500, 1000);
await this.page.type('#cardNumber', card.number, { delay: 100 });
// 4. 填写有效期(月份/年份)
logger.info(this.siteName, ' → 填写有效期...');
await this.page.click('#cardExpiry');
await this.human.randomDelay(300, 500);
const expiry = `${card.month}${card.year}`; // 格式: MMYY
await this.page.type('#cardExpiry', expiry, { delay: 100 });
// 5. 填写CVC
logger.info(this.siteName, ' → 填写CVC...');
await this.page.click('#cardCvc');
await this.human.randomDelay(300, 500);
await this.page.type('#cardCvc', card.cvv, { delay: 100 });
// 6. 填写持卡人姓名
logger.info(this.siteName, ' → 填写持卡人姓名...');
await this.page.click('#billingName');
await this.human.randomDelay(300, 500);
const fullName = `${this.accountData.firstName} ${this.accountData.lastName}`;
await this.page.type('#billingName', fullName, { delay: 100 });
// 7. 选择地址:中国澳门特别行政区
logger.info(this.siteName, ' → 选择地址:中国澳门特别行政区...');
await this.page.select('#billingCountry', 'MO');
await this.human.randomDelay(1000, 2000);
// 8. 填写地址信息(如果需要)
// 等待地址字段加载
await this.human.randomDelay(1000, 2000);
// 检查是否需要填写地址行1和行2
const addressFields = await this.page.$$('input[placeholder*="地址"]');
if (addressFields.length > 0) {
logger.info(this.siteName, ' → 填写地址信息...');
// 填写简单的地址
await addressFields[0].type('Macau', { delay: 100 });
if (addressFields[1]) {
await this.human.randomDelay(300, 500);
await addressFields[1].type('Macao', { delay: 100 });
}
}
// 9. 点击订阅按钮
logger.info(this.siteName, ' → 点击订阅按钮...');
await this.human.randomDelay(2000, 3000);
const submitButton = await this.page.$('button[type="submit"][data-testid="hosted-payment-submit-button"]');
if (submitButton) {
await submitButton.click();
logger.success(this.siteName, ' → ✓ 已点击订阅按钮');
// 等待处理
await this.human.randomDelay(5000, 7000);
this.currentStep = 6;
logger.success(this.siteName, `步骤 6 完成`);
} else {
logger.warn(this.siteName, ' → 未找到订阅按钮');
this.currentStep = 6;
}
} catch (error) {
logger.error(this.siteName, `填写支付信息失败: ${error.message}`);
throw error;
}
}
/**
* 执行注册流程
* @param {Object} options - 选项