// ==================== 配置参数(根据实际情况修改)====================
const CONFIG = {
// 抢购时间(格式:"时:分:秒",如 "10:00:00",建议提前 1-2 秒)
BUY_TIME: "10:00:00",
// 农行 APP 包名(无需修改,主流版本通用)
ABC_PACKAGE: "com.abchina.mobilebank",
// 洗车券相关关键词(可根据 APP 内显示调整)
COUPON_KEYWORDS: ["1元洗车", "洗车券", "1元洗车权益"],
// 抢购按钮关键词(可根据按钮文字调整)
BUY_BUTTON_KEYWORDS: ["立即抢购", "秒杀", "抢券"],
// 重试次数(抢券失败后自动重试,避免网络延迟)
RETRY_COUNT: 3,
// 点击偏移量(避免点击同一位置被判定为机器人,单位:像素)
CLICK_OFFSET: 5
};

// ==================== 工具函数 ====================
/**

  • 格式化时间为 "时:分:秒"
    */
    function formatTime(date) {
    const h = date.getHours().toString().padStart(2, "0");
    const m = date.getMinutes().toString().padStart(2, "0");
    const s = date.getSeconds().toString().padStart(2, "0");
    return ${h}:${m}:${s};
    }

/**

  • 等待指定毫秒数
    */
    function sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
    }

/**

  • 随机偏移点击(防机器人检测)
    */
    async function randomClick(x, y) {
    const offsetX = Math.floor(Math.random() * CONFIG.CLICK_OFFSET * 2) - CONFIG.CLICK_OFFSET;
    const offsetY = Math.floor(Math.random() * CONFIG.CLICK_OFFSET * 2) - CONFIG.CLICK_OFFSET;
    const finalX = Math.max(0, Math.min(device.width - 1, x + offsetX));
    const finalY = Math.max(0, Math.min(device.height - 1, y + offsetY));
    await click(finalX, finalY);
    console.log(随机点击位置:(${finalX}, ${finalY}));
    }

/**

  • 查找并点击包含关键词的控件
  • @param {string[]} keywords - 关键词数组
  • @param {number} timeout - 查找超时时间(毫秒)
  • @returns {boolean} 是否找到并点击
    */
    async function findAndClick(keywords, timeout = 3000) {
    const startTime = Date.now();
    while (Date.now() - startTime < timeout) {
    for (const keyword of keywords) {
    const widgets = id("").textContains(keyword).find();
    if (widgets.length > 0) {
    const target = widgets[0]; // 优先选择第一个匹配控件
    const bounds = target.bounds();
    await randomClick(bounds.centerX(), bounds.centerY());
    console.log(找到关键词「${keyword}」,已点击);
    return true;
    }
    }
    await sleep(100); // 每 100ms 查找一次
    }
    console.log(超时未找到关键词:${keywords.join("、")});
    return false;
    }

/**

  • 处理弹窗(关闭提示框、广告等)
    */
    async function handlePopups() {
    // 常见弹窗关闭关键词
    const closeKeywords = ["关闭", "取消", "知道了", "稍后"];
    await findAndClick(closeKeywords, 1000);
    }

// ==================== 核心抢购逻辑 ====================
async function startGrabCoupon() {
try {
console.log("===== 开始执行 1 元洗车券抢购脚本 =====");
console.log(配置参数:${JSON.stringify(CONFIG)});

// 1. 检查设备权限
if (!device.isRooted() && !auto.serviceRunning()) {
  toast("请开启无障碍服务后重试!");
  console.error("无障碍服务未开启");
  return;
}

// 2. 打开农行 APP
console.log("正在打开农行 APP...");
app.startActivity({
  packageName: CONFIG.ABC_PACKAGE,
  action: "android.intent.action.MAIN"
});
await sleep(5000); // 等待 APP 加载完成(根据手机性能调整)

// 3. 等待抢购时间
const targetTime = new Date();
const [h, m, s] = CONFIG.BUY_TIME.split(":").map(Number);
targetTime.setHours(h, m, s, 0);
const now = new Date();

if (now < targetTime) {
  const waitTime = targetTime - now;
  console.log(`当前时间:${formatTime(now)},抢购时间:${CONFIG.BUY_TIME}`);
  console.log(`需等待 ${Math.floor(waitTime / 1000)} 秒...`);
  toast(`等待抢购时间,剩余 ${Math.floor(waitTime / 1000)} 秒`);
  
  // 提前 2 秒唤醒屏幕(防止息屏)
  await sleep(waitTime - 2000);
  device.wakeUp(); // 唤醒屏幕
  await sleep(2000);
}

// 4. 定位洗车券入口(循环查找,兼容多入口)
console.log("正在查找洗车券入口...");
let enterSuccess = false;
for (let i = 0; i < 2; i++) { // 最多尝试 2 次(防止首次未找到)
  enterSuccess = await findAndClick(CONFIG.COUPON_KEYWORDS, 3000);
  if (enterSuccess) break;
  await swipe(device.width / 2, device.height * 0.8, device.width / 2, device.height * 0.3, 500); // 向上滑动(查找更多入口)
  await sleep(1000);
}

if (!enterSuccess) {
  toast("未找到洗车券入口,请检查关键词或 APP 页面!");
  console.error("未找到洗车券入口");
  return;
}
await sleep(2000); // 等待页面加载

// 5. 执行抢购(带重试机制)
let buySuccess = false;
for (let i = 0; i < CONFIG.RETRY_COUNT; i++) {
  console.log(`第 ${i + 1} 次尝试抢购...`);
  handlePopups(); // 先关闭可能的弹窗
  
  buySuccess = await findAndClick(CONFIG.BUY_BUTTON_KEYWORDS, 1000);
  if (buySuccess) {
    toast("抢购点击成功!请手动确认订单~");
    console.log("抢购点击成功,等待订单确认");
    await sleep(3000);
    // 尝试点击"确认"按钮(如果有订单确认步骤)
    await findAndClick(["确认", "提交订单"], 2000);
    break;
  }
  
  // 抢购失败,刷新页面(向下滑动刷新)
  await swipe(device.width / 2, device.height * 0.3, device.width / 2, device.height * 0.8, 500);
  await sleep(1000);
}

if (!buySuccess) {
  toast("抢购失败,请检查网络或券已售罄!");
  console.error("抢购失败,重试次数用尽");
}

console.log("===== 脚本执行结束 =====");

} catch (error) {
console.error("脚本执行出错:", error);
toast(脚本出错:${error.message});
}
}

bsplin · 20 小时前

回答

Hamibot AI
1
· 20 小时前

你提供的代码是一个用于抢购1元洗车券的脚本,适用于Hamibot平台。以下是对你代码的一些建议和说明:

1. 配置参数

  • BUY_TIME:设置抢购时间,建议提前1-2秒,确保在目标时间开始前触发。
  • ABC_PACKAGE:农行APP的包名,无需修改。
  • COUPON_KEYWORDS:用于查找洗车券入口的关键词,可以根据实际APP界面调整。
  • BUY_BUTTON_KEYWORDS:用于查找抢购按钮的关键词,根据按钮文字调整。
  • RETRY_COUNT:抢购失败后的重试次数,避免因网络延迟导致的失败。
  • CLICK_OFFSET:点击偏移量,防止被判定为机器人。

2. 工具函数

  • formatTime:格式化时间为"时:分:秒"。
  • sleep:等待指定毫秒数。
  • randomClick:随机偏移点击,防机器人检测。
  • findAndClick:查找并点击包含关键词的控件。
  • handlePopups:处理弹窗(关闭提示框、广告等)。

3. 核心抢购逻辑

  • 检查设备权限:确保无障碍服务已开启。
  • 打开农行APP:启动农行APP并等待加载完成。
  • 等待抢购时间:计算抢购时间并等待。
  • 定位洗车券入口:循环查找洗车券入口,兼容多入口。
  • 执行抢购:带重试机制,尝试抢购并处理可能的弹窗。

4. 注意事项

  • 确保设备已开启无障碍服务和后台弹窗权限。
  • 根据实际APP界面调整关键词,例如COUPON_KEYWORDSBUY_BUTTON_KEYWORDS
  • 如果抢购失败,可以尝试增加重试次数或调整等待时间。
  • 注意不要频繁操作,以免被系统判定为异常行为。

如果你有其他问题或需要进一步的帮助,请随时告诉我!

ℹ️ 本回答由 AI 生成,内容仅供参考