智能订单审核

根据多重条件自动审核大额订单

目前為 2025-08-08 提交的版本,檢視 最新版本

// ==UserScript==
// @name         智能订单审核
// @namespace    http://tampermonkey.net/
// @version      1.1.135
// @description  根据多重条件自动审核大额订单
// @author       Cisco
// @match        https://7777m.topcms.org/*
// @match        https://111bet22.topcms.org/*
// @match        https://888bet.topcms.org/*
// @match        https://hkgame.topcms.org/*
// @match        https://666bet.topcms.org/*
// @match        https://k9.topcms.org/*
// @icon         https://7777m.topcms.org/favicon.ico
// @license      MIT
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_addStyle
// ==/UserScript==

(function () {
  "use strict";

  // 配置参数
  const rawConfig = {
    currentPage: 1, // 当前页码
    totalPages: 1, // 总页数
    pageSize: 200, // 每页订单数量
    isLastPage: false, // 是否是最后一页
    maxWithdrawAmount: 50, // 最大提现金额
    betToBonusRatio: 20, // 总投注额/赠送总额最小比率
    betToRechargeRatio: 5, // 总投注额/订单充值最小比率
    profitToRechargeRatio: 3, // 游戏盈亏/订单充值最大比率
    maxSameIPUsers: 2, // 最大相同IP用户数
    minBalance: 5, // 最小余额要求
    maxWithdrawTimes: 3, // 最大提现次数
    password: "", // 充值密码
    processedOrders: GM_getValue("processedOrders", {}), // 已处理订单记录
    payOutOrders: GM_getValue("payOutOrders", {}), // 已出款订单记录
    currentOrderId: null, // 当前处理的订单ID
    isProcessing: false, // 是否正在处理中
    isReturning: false, // 是否正在返回订单页面
    panelCollapsed: false, // 面板是否收起
    completedOneRound: false, // 是否完成了一轮处理
    processingOrderId: null, // 正在处理的订单ID
    totalBetAmount: 0, // 当前订单的总投注额
    profitAmount: 0, // 当前订单的游戏盈亏
  };

  // 使用 Proxy 监听 config 变化
  const config = new Proxy(rawConfig, {
    set(target, prop, value) {
      target[prop] = value;
  
      if (prop === "currentOrderId") {
        const el = document.getElementById("currentOrderId");
        if (el) el.textContent = value || "";
      }
  
      return true;
    }
  });

  // 添加控制面板样式
  GM_addStyle(`
        .monitor-panel-order {
            position: fixed;
            top: 20px;
            right: 80px;
            z-index: 9999;
            background: white;
            padding: 15px;
            border: 1px solid #ddd;
            border-radius: 5px;
            box-shadow: 0 2px 10px rgba(0,0,0,0.1);
            font-family: Arial, sans-serif;
            width: 320px;
            max-height: 90vh;
            overflow-y: auto;
            transition: all 0.3s ease;
        }
        .monitor-panel-order.collapsed {
            width: 40px;
            height: 40px;
            overflow: hidden;
            padding: 5px;
        }
        .toggle-panel {
            position: absolute;
            top: 5px;
            right: 5px;
            width: 30px;
            height: 30px;
            border: none;
            background: #f0f0f0;
            border-radius: 50%;
            cursor: pointer;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 16px;
            z-index: 10000;
        }
        .toggle-panel:hover {
            background: #e0e0e0;
        }
        .collapsed .panel-content {
            display: none;
        }
        .monitor-header {
            margin: 0 0 15px 0;
            color: #409EFF;
            font-size: 16px;
            font-weight: bold;
            border-bottom: 1px solid #eee;
            padding-bottom: 10px;
        }
        .config-group {
            margin-bottom: 12px;
            position: relative;
        }
        .config-label {
            display: block;
            margin-bottom: 5px;
            color: #666;
            font-size: 13px;
            font-weight: bold;
        }
        .config-label.required:after {
            content: " *";
            color: #F56C6C;
        }
        .config-input {
            width: 100%;
            padding: 8px;
            border: 1px solid #ddd;
            border-radius: 4px;
            box-sizing: border-box;
        }
        .config-input.error {
            border-color: #F56C6C;
        }
        .error-message {
            color: #F56C6C;
            font-size: 12px;
            margin-top: 3px;
            display: none;
        }
        .monitor-button {
            width: 100%;
            padding: 10px;
            background: #409EFF;
            color: white;
            border: none;
            border-radius: 4px;
            font-weight: bold;
            cursor: pointer;
            transition: background 0.3s;
            margin-bottom: 10px;
        }
        .monitor-button:disabled {
            background: #C0C4CC;
            cursor: not-allowed;
        }
        .monitor-button.stop {
            background: #F56C6C;
        }
        .monitor-stats {
            margin-top: 15px;
            font-size: 12px;
            color: #666;
            border-top: 1px solid #eee;
            padding-top: 10px;
        }
        .monitor-stat-row {
            display: flex;
            justify-content: space-between;
            margin-bottom: 5px;
        }
        .monitor-progress-container {
            margin: 10px 0;
            height: 10px;
            background: #f0f0f0;
            border-radius: 5px;
            overflow: hidden;
        }
        .monitor-progress-bar {
            height: 100%;
            background: linear-gradient(to right, #67C23A, #409EFF);
            transition: width 0.3s;
        }
        #statusText {
            font-weight: bold;
            color: #409EFF;
        }
        #processedCount {
            font-weight: bold;
            color: #67C23A;
        }
        .button-container {
            display: flex;
            flex-direction: column;
        }
        .monitor-button.hidden {
            display: none;
        }
    `);

  // 验证输入参数
  function validateInputs() {
    let isValid = true;
    const inputs = [
      { id: "maxAmount", name: "最大提现金额" },
      { id: "betBonusRatio", name: "总投注额大于赠送总额指定倍数" },
      { id: "betRechargeRatio", name: "总投注额大于订单充值指定倍数" },
      { id: "profitRatio", name: "游戏盈亏小于订单充值指定倍数" },
      { id: "maxSameIPUsers", name: "最大相同IP用户数" },
      { id: "minBalance", name: "最小余额要求" },
      { id: "maxWithdrawTimes", name: "最大提现次数" },
      { id: "withdrawPassword", name: "充值密码" },
    ];

    inputs.forEach((input) => {
      const element = document.getElementById(input.id);
      const errorElement =
        element.parentElement.querySelector(".error-message") ||
        createErrorElement(element.parentElement);

      if (input.id === "withdrawPassword") {
        if (!element.value.trim()) {
          element.classList.add("error");
          errorElement.textContent = `${input.name}不能为空`;
          errorElement.style.display = "block";
          isValid = false;
        } else {
          element.classList.remove("error");
          errorElement.style.display = "none";
        }
      } else {
        if (!element.value.trim()) {
          element.classList.add("error");
          errorElement.textContent = `${input.name}不能为空`;
          errorElement.style.display = "block";
          isValid = false;
        } else if (isNaN(element.value)) {
          element.classList.add("error");
          errorElement.textContent = `${input.name}必须是数字`;
          errorElement.style.display = "block";
          isValid = false;
        } else {
          element.classList.remove("error");
          errorElement.style.display = "none";
        }
      }
    });

    return isValid;
  }

  // 创建错误提示元素
  function createErrorElement(parent) {
    const errorElement = document.createElement("div");
    errorElement.className = "error-message";
    parent.appendChild(errorElement);
    return errorElement;
  }

  // 更新按钮显示状态
  function updateButtonVisibility() {
    const startBtn = document.getElementById("startBtn");
    const stopBtn = document.getElementById("stopBtn");

    if (config.isProcessing) {
      startBtn.classList.add("hidden");
      stopBtn.classList.remove("hidden");
    } else {
      startBtn.classList.remove("hidden");
      stopBtn.classList.add("hidden");
    }
  }

  // 添加控制面板
  function addControlPanel() {
    const panel = document.createElement("div");
    panel.className = "monitor-panel-order";
    panel.id = "autoWithdrawPanel";

    // 添加收起/展开按钮
    const toggleBtn = document.createElement("button");
    toggleBtn.className = "toggle-panel";
    toggleBtn.innerHTML = "×";
    toggleBtn.title = "收起/展开控制面板";
    toggleBtn.addEventListener("click", togglePanel);

    // 面板内容
    const panelContent = document.createElement("div");
    panelContent.className = "panel-content";
    panelContent.innerHTML = `
            <h3 class="monitor-header">智能自动出款系统</h3>
            <div class="config-group">
                <label class="config-label required">最大提现金额</label>
                <input type="number" class="config-input" id="maxAmount" value="${
                  config.maxWithdrawAmount
                }" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">总投注额大于赠送总额指定倍数</label>
                <input type="number" class="config-input" id="betBonusRatio" value="${
                  config.betToBonusRatio
                }" step="0.1" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">总投注额大于订单充值指定倍数</label>
                <input type="number" class="config-input" id="betRechargeRatio" value="${
                  config.betToRechargeRatio
                }" step="0.1" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">游戏盈亏小于订单充值指定倍数</label>
                <input type="number" class="config-input" id="profitRatio" value="${
                  config.profitToRechargeRatio
                }" step="0.1" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">最大相同IP用户数</label>
                <input type="number" class="config-input" id="maxSameIPUsers" value="${
                  config.maxSameIPUsers
                }" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">最小余额要求</label>
                <input type="number" class="config-input" id="minBalance" value="${
                  config.minBalance
                }" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">最大提现次数</label>
                <input type="number" class="config-input" id="maxWithdrawTimes" value="${
                  config.maxWithdrawTimes
                }" required>
                <div class="error-message"></div>
            </div>
            <div class="config-group">
                <label class="config-label required">充值密码</label>
                <input type="text" class="config-input" id="withdrawPassword" value="${
                  config.password
                }" required>
                <div class="error-message"></div>
            </div>
            <div class="button-container">
                <button id="startBtn" class="monitor-button ${
                  config.isProcessing ? "hidden" : ""
                }">开始处理</button>
                <button id="stopBtn" class="monitor-button stop ${
                  !config.isProcessing ? "hidden" : ""
                }">停止处理</button>
            </div>
            <div class="button-container">
                <button id="clearCacheBtn" class="monitor-button">清理缓存</button>
            </div>

            <div class="monitor-stats">
                <div class="monitor-stat-row">
                    <span>状态:</span>
                    <span id="statusText">待命</span>
                </div>
                <div class="monitor-stat-row">
                    <span>当前处理:</span>
                    <span id="currentOrderId">${Object.keys(config.currentOrderId)}</span>
                </div>
                <div class="monitor-stat-row">
                    <span>已处理:</span>
                    <span id="processedCount">${
                      Object.keys(config.processedOrders).length
                    }</span> 单
                </div>
                <div class="monitor-stat-row">
                    <span>已出款:</span>
                    <span id="payOutOrders">${Object.keys(
                      config.payOutOrders
                    ).join(", ")}</span>
                </div>
            </div>
        `;

    panel.appendChild(toggleBtn);
    panel.appendChild(panelContent);
    document.body.appendChild(panel);

    // 恢复面板状态
    config.panelCollapsed = GM_getValue("panelCollapsed", false);
    if (config.panelCollapsed) {
      panel.classList.add("collapsed");
      toggleBtn.innerHTML = "≡";
    }

    // 事件监听
    document.getElementById("startBtn").addEventListener("click", function () {
      if (validateInputs()) {
        startProcessing();
      }
    });
    document
      .getElementById("stopBtn")
      .addEventListener("click", stopProcessing);

    // 为所有输入框添加实时验证
    document.querySelectorAll(".config-input").forEach((input) => {
      input.addEventListener("input", function () {
        validateInputs();
      });
    });

    // 绑定清理缓存事件
    document
      .getElementById("clearCacheBtn")
      .addEventListener("click", function () {
        if (confirm("确定要清理缓存数据吗?这会清空已处理订单记录。")) {
          // 清空内存中的数据
          config.processedOrders = {};
          config.payOutOrders = {};
          config.currentOrderId = null;

          // 清空本地存储
          GM_setValue("processedOrders", {});
          GM_setValue("payOutOrders", {});
          GM_setValue("currentOrderId", null);

          // 更新计数和显示
          document.getElementById("processedCount").textContent = "0";
          document.getElementById("payOutOrders").textContent = "";
          document.getElementById("currentOrderId").textContent = "";

          updateStatus("缓存已清理");
        }
      });
  }

  // 收起/展开面板
  function togglePanel() {
    const panel = document.getElementById("autoWithdrawPanel");
    config.panelCollapsed = !panel.classList.contains("collapsed");

    if (config.panelCollapsed) {
      panel.classList.add("collapsed");
      this.innerHTML = "≡";
    } else {
      panel.classList.remove("collapsed");
      this.innerHTML = "×";
    }

    GM_setValue("panelCollapsed", config.panelCollapsed);
  }

  async function setPageSizeFast(targetSize = 200) {
    const pagination = document.querySelector('.el-pagination');
    if (!pagination) throw new Error('未找到分页组件');
  
    const sizeInput = pagination.querySelector('.el-select .el-input');
    if (!sizeInput) throw new Error('未找到下拉输入框');
  
    // 打开下拉菜单
    sizeInput.click();
  
    // 等待下拉项出现
    const item = await waitForDropdownItem(targetSize);
    if (!item) throw new Error(`未找到 ${targetSize} 条/页 选项`);
  
    item.click();
    console.log(`✅ 成功切换到每页 ${targetSize} 条`);
  
  }

// 等待指定分页选项出现
function waitForDropdownItem(size, maxTries = 10) {
    return new Promise((resolve) => {
      let tries = 0;
  
      function check() {
        const items = document.querySelectorAll('.el-select-dropdown__item span');
        const match = Array.from(items).find(span => span.textContent.includes(size + '条'));
        if (match) return resolve(match.parentElement);
        if (++tries >= maxTries) return resolve(null);
        requestAnimationFrame(check);
      }
  
      check();
    });
  }

  // 获取分页信息
  function updatePaginationInfo() {
    const pagination = document.querySelector(".el-pagination");
    if (!pagination) {
      console.error("无法找到分页元素");
      // 默认值
      config.currentPage = 1;
      config.totalPages = 1;
      config.isLastPage = true;
      return;
    }

    // 当前页
    const activePage = pagination.querySelector(".el-pager .number.active");
    config.currentPage = activePage ? parseInt(activePage.textContent) : 1;

    // 每页数量
    const pageSizeSelect = pagination.querySelector(
      ".el-select-dropdown__item.selected"
    );
    config.pageSize = pageSizeSelect
      ? parseInt(pageSizeSelect.textContent)
      : null;

    // 总条数
    let totalItems = null;
    const totalTextEl = pagination.querySelector(".el-pagination__total");
    if (totalTextEl) {
      const totalMatch = totalTextEl.textContent.match(/共\s*(\d+)\s*条/);
      if (totalMatch) {
        totalItems = parseInt(totalMatch[1]);
      }
    }

    // 计算总页数
    if (totalItems !== null && config.pageSize) {
      config.totalPages = Math.ceil(totalItems / config.pageSize);
    } else {
      // 如果没法算,用当前页作为总页数兜底
      config.totalPages = config.currentPage || 1;
    }

    // 是否最后一页
    const nextBtn = pagination.querySelector(".btn-next");
    if (config.totalPages === 1) {
      config.isLastPage = true; // 只有一页直接是最后一页
    } else if (nextBtn) {
      config.isLastPage = nextBtn.disabled;
    } else {
      // 没有下一页按钮时,如果当前页是总页数,也认为是最后一页
      config.isLastPage = config.currentPage >= config.totalPages;
    }

    console.log(
      `当前页码: ${config.currentPage}/${config.totalPages}`,
      `每页: ${config.pageSize || "-"}条`,
      `是否末页: ${config.isLastPage}`
    );
  }

  // 跳转到最后一页
  function goToLastPage() {
    const pageInput = document.querySelector(".el-pagination__editor input");
    const jumpBtn = document.querySelector(".el-pagination__jump");

    if (pageInput && jumpBtn) {
      // 设置页码为总页数
      const setter = Object.getOwnPropertyDescriptor(
        HTMLInputElement.prototype,
        "value"
      ).set;
      setter.call(pageInput, config.totalPages);
      pageInput.dispatchEvent(new Event("input", { bubbles: true }));
      pageInput.dispatchEvent(new Event("change", { bubbles: true }));

      // 模拟回车键触发跳转
      setTimeout(() => {
        const enterEvent = new KeyboardEvent("keydown", {
          key: "Enter",
          code: "Enter",
          keyCode: 13,
          which: 13,
          bubbles: true,
        });
        pageInput.dispatchEvent(enterEvent);

        // 等待页面加载
        setTimeout(processOrderPage, 2000);
      }, 500);
    } else {
      console.error("无法找到分页跳转控件");
      setTimeout(processOrderPage, 3000);
    }
  }

  // 跳转到上一页
  function goToPrevPage() {
    const prevBtn = document.querySelector(
      ".el-pagination .btn-prev:not([disabled])"
    );
    if (prevBtn) {
      prevBtn.click();
      setTimeout(() => {
        config.currentPage--;
        processOrderPage();
      }, 2000);
    } else {
      updateStatus("已是第一页,处理完成");
      setTimeout(processOrderPage, 5000);
    }
  }

  // 开始处理
  function startProcessing() {
    if (config.isProcessing) return;

    // 更新配置
    updateConfig();

    config.isProcessing = true;
    updateStatus("开始处理订单...");
    updateButtonVisibility();

    // 检查当前页面
    if (isOrderPage()) {
      processOrderPage();
    } else if (isAgentPage()) {
      processAgentPage();
    } else {
      // 不在目标页面,跳转到订单页面
      updateStatus("正在跳转到订单页面...");
      window.location.href = "#/order/unread-withdraw";
    }
  }

  // 停止处理
  function stopProcessing() {
    config.isProcessing = false;
    config.processingOrderId = null;
    updateStatus("处理已停止");
    updateButtonVisibility();
  }

  // 更新配置
  function updateConfig() {
    config.maxWithdrawAmount = parseFloat(
      document.getElementById("maxAmount").value
    );
    config.betToBonusRatio = parseFloat(
      document.getElementById("betBonusRatio").value
    );
    config.betToRechargeRatio = parseFloat(
      document.getElementById("betRechargeRatio").value
    );
    config.profitToRechargeRatio = parseFloat(
      document.getElementById("profitRatio").value
    );
    config.maxSameIPUsers = parseInt(
      document.getElementById("maxSameIPUsers").value
    );
    config.minBalance = parseFloat(document.getElementById("minBalance").value);
    config.maxWithdrawTimes = parseInt(
      document.getElementById("maxWithdrawTimes").value
    );
    config.password = document.getElementById("withdrawPassword").value;
  }

  // 更新状态
  function updateStatus(text) {
    const statusEl = document.getElementById("statusText");
    if (statusEl) {
      statusEl.textContent = text;
    }
  }

  // 检查是否在订单页面
  function isOrderPage() {
    return window.location.hash.includes("#/order/unread-withdraw");
  }

  // 检查是否在代理页面
  function isAgentPage() {
    return window.location.hash.includes("#/agent/agent-list");
  }

  // 点击查询按钮的函数
  function clickSearchButton() {
    // 获取所有filter-container元素
    const filterContainers = document.querySelectorAll(".filter-container");

    // 第三个filter-container包含查询按钮
    if (filterContainers.length >= 3) {
      const searchContainer = filterContainers[2];

      // 查找查询按钮 - 确保不是禁用状态且文本是"查询"
      const searchBtn = Array.from(
        searchContainer.querySelectorAll("button.el-button")
      ).find((btn) => !btn.disabled && btn.textContent.includes("查询"));

      if (searchBtn) {
        updateStatus("点击查询按钮重新开始处理...");

        // 先清空所有搜索条件
        clearAllSearchInputs();

        // 点击查询按钮
        searchBtn.click();

        // 等待查询完成
        setTimeout(() => {
          config.processedOrders = {};
          GM_setValue("processedOrders", {});
          document.getElementById("processedCount").textContent = "0";
          config.completedOneRound = false;
          GM_setValue("completedOneRound", false);

          // 重新开始处理
          setTimeout(processOrderPage, 500);
        }, 1500);
        return;
      }
    }

    // 如果没找到按钮,尝试其他方式
    updateStatus("未找到查询按钮,3秒后尝试重新开始");
    setTimeout(processOrderPage, 3000);
  }

  // 清空所有搜索输入框的函数
  function clearAllSearchInputs() {
    // 清空订单号输入框
    const orderInput = document.querySelector(
      '.filter-container input[placeholder="请输入订单号"]'
    );
    if (orderInput) {
      orderInput.value = "";
      orderInput.dispatchEvent(new Event("input", { bubbles: true }));
    }

    // 清空用户ID输入框
    const userIdInput = document.querySelector(
      '.filter-container input[placeholder="请输入用户ID"]'
    );
    if (userIdInput) {
      userIdInput.value = "";
      userIdInput.dispatchEvent(new Event("input", { bubbles: true }));
    }

    // 重置第三方选择器
    const thirdPartySelect = document.querySelector(
      '.el-select input[placeholder="全部"]'
    );
    if (thirdPartySelect && thirdPartySelect.value !== "全部") {
      thirdPartySelect.value = "全部";
      thirdPartySelect.dispatchEvent(new Event("input", { bubbles: true }));
    }

    // 清空日期范围选择器
    const dateInputs = document.querySelectorAll(".el-range-input");
    dateInputs.forEach((input) => {
      if (input.value) {
        input.value = "";
        input.dispatchEvent(new Event("input", { bubbles: true }));
      }
    });
  }

  // 处理订单页面
  async function processOrderPage() {
    try {
        if (!config.isProcessing) return;

        if (config.processingOrderId) {
        // 不再反复打印日志
        return setTimeout(processOrderPage, 1000);
        }

        await setPageSizeFast(200);
        // 获取分页信息
        updatePaginationInfo();

        // 如果不是最后一页,先跳转到最后一页
        if (!config.isLastPage && config.currentPage < config.totalPages) {
        return goToLastPage();
        }

        const rows = document.querySelectorAll(
        ".el-table--scrollable-x .el-table__body .el-table__row"
        );
        if (rows.length === 0) {
            if (config.currentPage > 1) {
                goToPrevPage();
            } else {
                updateStatus("所有订单已处理完成");
                // 记录已完成一轮处理
                config.completedOneRound = true;
                GM_setValue("completedOneRound", true);

                // 5秒后点击查询按钮
                setTimeout(() => {
                clickSearchButton();
                }, 5000);
            }
            return;
        }

        // 从最后一行开始处理
        for (let i = rows.length - 1; i >= 0; i--) {
            const row = rows[i];
            const orderId = getOrderIdFromRow(row);
            console.log("订单号:", orderId);

            // 跳过已处理的订单
            if (config.processedOrders[orderId]) {
                console.log(`[跳过] 订单 ${orderId} 已处理`);
                continue;
            }

            config.processingOrderId = orderId; // 设置当前处理中的订单ID

            console.log(`[处理中] 页码 ${config.currentPage} 的订单 ${orderId}`);

            // 1.1 检查提现金额
            const amountNode = row.querySelector("td:nth-child(8) .cell > span"); // 第8列通常是金额列
            if (!amountNode) {
                // 如果第8列找不到,尝试其他可能的位置
                const amountNodes = row.querySelectorAll("td .cell > span");
                let foundAmount = false;

                for (const node of amountNodes) {
                // 检查是否是金额(包含数字和小数点)
                if (/^\d+\.\d{2}$/.test(node.textContent.trim())) {
                    amountNode = node;
                    foundAmount = true;
                    break;
                }
                }

                if (!foundAmount) {
                console.error("提取提现金额失败", row);
                markOrderAsProcessed(orderId, "格式错误");
                continue;
                }
            }

            const amount = parseFloat(amountNode.textContent);
            if (amount > config.maxWithdrawAmount) {
                console.log(`[跳过] 金额 ${amount} 超过限制`);
                markOrderAsProcessed(orderId, "金额超限");
                continue;
            }

            // 1.2-1.4 检查用户详情
            // 使用更稳定的选择器定位用户名元素
            const usernameEl = row.querySelector("td:nth-child(2) .el-tooltip"); // 用户名通常在第二列
            if (!usernameEl) {
                // 如果第二列找不到,尝试其他方式
                const usernameEls = row.querySelectorAll(".el-tooltip");
                if (usernameEls.length > 0) {
                    usernameEl = usernameEls[0]; // 取第一个el-tooltip元素
                } else {
                    console.error("找不到用户名元素", row);
                    markOrderAsProcessed(orderId, "格式错误");
                    continue;
                }
            }

            config.currentOrderId = orderId;
            config.currentProcessingRow = i; // 记录当前处理的行索引
            usernameEl.click();

            // 等待弹窗出现
            setTimeout(checkUserDetail, 1500);
            return; // 等待异步处理
        }

        // 当前页处理完成,跳转上一页
        if (config.currentPage > 1) {
            goToPrevPage();
        } else {
            updateStatus("已完成所有订单处理");
            // 记录已完成一轮处理
            config.completedOneRound = true;
            GM_setValue("completedOneRound", true);

            // 5秒后点击查询按钮
            setTimeout(() => {
                clickSearchButton();
            }, 5000);
        }

    } catch (e) {
        console.error("processOrderPage 异常:", e);
        config.processingOrderId = null;
        setTimeout(processOrderPage, 1000);
    }
  }

  // 检查用户详情弹窗
  function checkUserDetail() {
    // 如果当前没有在处理订单,则直接返回
    if (!config.isProcessing) {
      updateStatus("等待处理订单...");
      return;
    }

    // 查找当前显示的用户详情弹窗
    const dialog = document.querySelector(
      '.el-dialog__wrapper:not([style*="display: none"])'
    );
    if (!dialog) {
      updateStatus("等待用户详情弹窗...");
      // 1.5秒后重试
      setTimeout(checkUserDetail, 1500);
      return;
    }

    // 获取弹窗中的所有表格
    const tables = dialog.querySelectorAll(".el-table");

    // 第二个表格包含所需的财务数据(余额、投注额、充值等)
    const financialTable = tables[1];
    if (!financialTable) {
      closeDialogAndContinue();
      return;
    }

    // 获取财务表格中的所有数据单元格
    const cells = financialTable.querySelectorAll(
      ".el-table__body .cell > span"
    );

    // 按固定位置提取数值(索引从0开始)
    // 列顺序:余额, 误差, 订单充值, 订单提现, 提现手续费, 公积金购买, 通行证购买, 充提差, 游戏盈亏, 总投注额, 总打码量, 赠送总额
    const balanceText = cells[0]?.textContent || "0"; // 余额
    const totalRechargeText = cells[2]?.textContent || "0"; // 订单充值
    const profitText = cells[8]?.textContent || "0"; // 游戏盈亏
    const totalBetText = cells[9]?.textContent || "0"; // 总投注额
    const totalBonusText = cells[11]?.textContent || "0"; // 赠送总额

    // 第三个表格包含相同IP用户数
    const sameIPTable = tables[2];
    const sameIPUsersText =
      sameIPTable?.querySelector(".el-table__body .cell > span")?.textContent ||
      "0";

    // 数值解析函数
    const parseValue = (text) => {
      // 移除所有非数字字符(保留小数点和负号)
      const numStr = text.replace(/[^\d.-]/g, "");
      return parseFloat(numStr) || 0;
    };

    // 解析各数值
    const totalBet = parseValue(totalBetText); // 总投注额
    const totalBonus = parseValue(totalBonusText); // 赠送总额
    const totalRecharge = parseValue(totalRechargeText); // 订单充值
    const profit = parseValue(profitText); // 游戏盈亏
    const sameIPUsers = parseInt(sameIPUsersText) || 0; // 相同IP用户数
    const balance = parseValue(balanceText); // 余额

    config.totalBetAmount = totalBet; // 记录当前订单的总投注额
    config.profitAmount = profit; // 记录当前订单的游戏盈亏

    console.log("总投注额:", totalBet);
    console.log("赠送总额:", totalBonus);
    console.log("订单充值:", totalRecharge);
    console.log("游戏盈亏:", profit);
    console.log("相同IP用户数:", sameIPUsers);
    console.log("余额:", balance);

    // 1.2 检查总投注额 > 赠送总额 × 指定倍数
    if (totalBet <= totalBonus * config.betToBonusRatio) {
      
      updateStatus(
        `订单 ${config.currentOrderId} 投注额不满足大于赠送额指定倍数条件`
      );
      markOrderAsProcessed(config.currentOrderId, "不满足条件");
      closeDialogAndContinue();
      return;
    }

    // 1.3 检查总投注额 > 订单充值 × 指定倍数
    if (totalBet <= totalRecharge * config.betToRechargeRatio) {
      config.processingOrderId = null;
      updateStatus(
        `订单 ${config.currentOrderId} 投注额不满足大于充值额指定倍数条件`
      );
      markOrderAsProcessed(config.currentOrderId, "不满足条件");
      closeDialogAndContinue();
      return;
    }

    // 1.4 检查游戏盈亏绝对值 < 订单充值 × 指定倍数
    if (Math.abs(profit) > totalRecharge * config.profitToRechargeRatio) {
      updateStatus(
        `订单 ${config.currentOrderId} 盈亏不满足小于充值额指定倍数条件`
      );
      markOrderAsProcessed(config.currentOrderId, "不满足条件");
      closeDialogAndContinue();
      return;
    }

    // 检查相同IP用户数是否超过限制
    if (sameIPUsers > config.maxSameIPUsers) {
      updateStatus(`订单 ${config.currentOrderId} 相同IP用户数超过限制`);
      markOrderAsProcessed(config.currentOrderId, "相同IP用户数超限");
      closeDialogAndContinue();
      return;
    }

    // 检查用户余额是否满足最低要求
    if (balance < config.minBalance) {
      updateStatus(
        `订单 ${config.currentOrderId} 余额不足 (${balance} < ${config.minBalance})`
      );
      markOrderAsProcessed(config.currentOrderId, "余额不足");
      closeDialogAndContinue();
      return;
    }

    // 从用户信息区域提取用户ID
    const userIdEl = dialog.querySelector(
      ".el-table__row .cell div div:nth-child(3)"
    );
    const userId = userIdEl
      ? userIdEl.textContent.replace("ID:", "").trim()
      : null;
    config.currentUserId = userId;
    console.log("用户ID:", userId);

    // 关闭当前弹窗
    closeDialog();

    // 所有条件满足,跳转到提现订单页面进行下一步检查
    updateStatus(
      `订单 ${config.currentOrderId} 用户 ${userId} 满足条件,检查提现记录...`
    );
    setTimeout(() => {
      window.location.href = "#/order/order-withdraw";
    }, 1000);
  }

  // 从弹窗中提取用户ID
  function findUserIdFromDialog(dialog) {
    if (!dialog) return null;

    const divs = dialog.querySelectorAll("div");
    for (const div of divs) {
      const text = div.textContent?.trim();
      if (text?.startsWith("ID:")) {
        return text.replace("ID:", "").trim();
      }
    }

    return null;
  }

  // 处理提现订单页面
  function processWithdrawOrderPage() {
    if (!config.isProcessing) return;

    console.log("正在处理提现订单页面,用户ID:", config.currentUserId);

    let retryCount = 0;
    const maxRetries = 5;
    const retryInterval = 1000;

    const tryProcess = () => {
      retryCount++;
      console.log(`尝试处理提现订单页面 (第 ${retryCount} 次)`);

      // 1. 查找用户ID输入框 - 根据提供的HTML结构调整选择器
      const idInput = document.querySelector(
        'input[placeholder="请输入用户ID"].el-input__inner'
      );

      if (!idInput) {
        if (retryCount < maxRetries) {
          console.log("未找到用户ID输入框,等待重试...");
          setTimeout(tryProcess, retryInterval);
          return;
        } else {
          console.error("多次重试后仍未找到用户ID输入框");
          return;
        }
      }

      // 2. 设置用户ID值
      try {
        // 更可靠的值设置方式
        idInput.focus();
        idInput.value = "";

        // 使用原生方法设置值
        const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
          HTMLInputElement.prototype,
          "value"
        ).set;
        nativeInputValueSetter.call(idInput, config.currentUserId);

        // 触发所有必要事件
        ["input", "change", "blur"].forEach((eventType) => {
          idInput.dispatchEvent(new Event(eventType, { bubbles: true }));
        });

        console.log("已设置用户ID:", config.currentUserId);

        // 3. 调整日期范围
        setTimeout(() => {
          adjustDateTimeRange();

          // 查找下拉菜单容器(可能在body的末尾)
          const dropdown = document.querySelectorAll(
            ".el-select-dropdown.el-popper"
          );
          if (!dropdown) {
            console.error("找不到下拉菜单");
            returnToOrderPage();
            return;
          }

          const payItems = dropdown[0]; // 取第一个
          // 查找已支付选项
          const items = payItems.querySelectorAll(".el-select-dropdown__item");
          let payItem = null;
          for (const item of items) {
            if (item.textContent.trim().toLowerCase() === "已支付") {
              payItem = item;
              break;
            }
          }

          if (!payItem) {
            console.error("找不到已支付选项");
            // 没有已支付选项,继续代理检查
            updateStatus(
              `用户 ${config.currentUserId} 无充值记录,返回订单列表`
            );
            setTimeout(() => {
              processOrderPage();
            }, 1000);
            return;
          }

          // 选择已支付选项
          payItem.click();

          // 4. 查找并点击查询按钮 - 根据提供的HTML结构调整选择器
          const queryBtn = Array.from(
            document.querySelectorAll(".filter-container button.el-button")
          ).find((btn) => {
            const span = btn.querySelector("span");
            return span && span.textContent.trim() === "查询";
          });

          if (queryBtn) {
            console.log("找到查询按钮,正在点击...");
            queryBtn.click();
            setTimeout(checkWithdrawTimes, 2000);
          } else {
            console.error("未找到查询按钮");
            setTimeout(checkWithdrawTimes, 1000);
          }
        }, 300);
      } catch (error) {
        console.error("设置用户ID时出错:", error);
        if (retryCount < maxRetries) {
          setTimeout(tryProcess, retryInterval);
        }
      }
    };

    // 初始尝试
    setTimeout(tryProcess, 1500); // 给页面一点加载时间
  }

  // 调整日期时间范围(减8小时)
  function adjustDateTimeRange() {
    // 找到日期范围输入框
    const dateRangeInputs = document.querySelectorAll(".el-range-input");
    if (dateRangeInputs.length < 2) {
      console.error("找不到日期范围输入框");
      return;
    }

    const startInput = dateRangeInputs[0];
    const endInput = dateRangeInputs[1];

    // 获取当前日期时间
    const now = new Date();
    const endDate = new Date(
      now.getFullYear(),
      now.getMonth(),
      now.getDate(),
      23,
      59,
      59
    );
    const startDate = new Date(
      now.getFullYear(),
      now.getMonth(),
      now.getDate(),
      0,
      0,
      0
    );

    // 减8小时
    startDate.setHours(startDate.getHours() - 8);
    endDate.setHours(endDate.getHours() - 8);

    // 格式化日期时间
    const formatDate = (date) => {
      const pad = (num) => num.toString().padStart(2, "0");
      return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
        date.getDate()
      )} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
        date.getSeconds()
      )}`;
    };

    // 设置日期时间
    const setter = Object.getOwnPropertyDescriptor(
      HTMLInputElement.prototype,
      "value"
    ).set;
    setter.call(startInput, formatDate(startDate));
    startInput.dispatchEvent(new Event("input", { bubbles: true }));

    setter.call(endInput, formatDate(endDate));
    endInput.dispatchEvent(new Event("input", { bubbles: true }));

    console.log(
      "已调整日期时间范围:",
      formatDate(startDate),
      "至",
      formatDate(endDate)
    );
  }

  // 调整日期时间范围(7天内减8小时)
  function adjustDateTimeRange7d() {
    // 找到日期范围输入框
    const dateRangeInputs = document.querySelectorAll(".el-range-input");
    if (dateRangeInputs.length < 2) {
      console.error("找不到日期范围输入框");
      return;
    }

    const startInput = dateRangeInputs[0];
    const endInput = dateRangeInputs[1];

    // 获取当前日期时间
    const now = new Date();
    const endDate = new Date(
      now.getFullYear(),
      now.getMonth(),
      now.getDate(),
      23,
      59,
      59
    );
    const startDate = new Date(
      now.getFullYear(),
      now.getMonth(),
      now.getDate(),
      0,
      0,
      0
    );

    // 减8小时
    startDate.setDate(startDate.getDate() - 6);
    startDate.setHours(startDate.getHours() - 8);
    endDate.setHours(endDate.getHours() - 8);

    // 格式化日期时间
    const formatDate = (date) => {
      const pad = (num) => num.toString().padStart(2, "0");
      return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(
        date.getDate()
      )} ${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(
        date.getSeconds()
      )}`;
    };

    // 设置日期时间
    const setter = Object.getOwnPropertyDescriptor(
      HTMLInputElement.prototype,
      "value"
    ).set;
    setter.call(startInput, formatDate(startDate));
    startInput.dispatchEvent(new Event("input", { bubbles: true }));

    setter.call(endInput, formatDate(endDate));
    endInput.dispatchEvent(new Event("input", { bubbles: true }));

    console.log(
      "已调整日期时间范围:",
      formatDate(startDate),
      "至",
      formatDate(endDate)
    );
  }

  // 处理充值订单页面
  function processTopupOrderPage() {
    if (!config.isProcessing) return;

    console.log("正在处理充值订单页面,用户ID:", config.currentUserId);

    let retryCount = 0;
    const maxRetries = 5;
    const retryInterval = 1000;

    const tryProcess = () => {
      retryCount++;
      console.log(`尝试处理充值订单页面 (第 ${retryCount} 次)`);

      // 1. 查找用户ID输入框
      const idInput = document.querySelector(
        'input[placeholder="请输入用户ID"].el-input__inner'
      );

      if (!idInput) {
        if (retryCount < maxRetries) {
          console.log("未找到用户ID输入框,等待重试...");
          setTimeout(tryProcess, retryInterval);
          return;
        } else {
          console.error("多次重试后仍未找到用户ID输入框");
          markOrderAsProcessed(config.currentOrderId, "获取充值记录失败");
          returnToOrderPage();
          return;
        }
      }

      // 2. 设置用户ID值
      try {
        // 清空并设置用户ID
        idInput.focus();
        idInput.value = "";

        const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
          HTMLInputElement.prototype,
          "value"
        ).set;
        nativeInputValueSetter.call(idInput, config.currentUserId);

        // 触发事件
        ["input", "change", "blur"].forEach((eventType) => {
          idInput.dispatchEvent(new Event(eventType, { bubbles: true }));
        });

        console.log("已设置用户ID:", config.currentUserId);

        // 找到订单状态下拉选择框
        const orderStatusSelect = document.querySelector(
          '.el-select input[placeholder="全部状态"]'
        );
        if (!orderStatusSelect) {
          console.error("找不到订单状态下拉选择框");
          setTimeout(() => {
            processTopupOrderPage();
          }, 1000);
          return;
        }
        // 3. 设置订单状态为"已支付"
        setTimeout(() => {
          // 查找下拉菜单容器(可能在body的末尾)
          const dropdown = document.querySelectorAll(
            ".el-select-dropdown.el-popper"
          );
          if (!dropdown) {
            console.error("找不到下拉菜单");
            returnToOrderPage();
            return;
          }

          const payItems = dropdown[0]; // 取第一个
          // 查找已支付选项
          const items = payItems.querySelectorAll(".el-select-dropdown__item");
          let payItem = null;
          for (const item of items) {
            if (item.textContent.trim().toLowerCase() === "已支付") {
              payItem = item;
              break;
            }
          }

          if (!payItem) {
            console.error("找不到已支付选项");
            // 没有已支付选项,继续代理检查
            updateStatus(
              `用户 ${config.currentUserId} 无充值记录,返回订单列表`
            );
            setTimeout(() => {
              processOrderPage();
            }, 1000);
            return;
          }

          // 选择已支付选项
          payItem.click();

          // 点击查询按钮
          setTimeout(() => {
            const queryBtn = Array.from(
              document.querySelectorAll(".filter-container button.el-button")
            ).find((btn) => {
              const span = btn.querySelector("span");
              return span && span.textContent.trim() === "查询";
            });

            if (queryBtn) {
              console.log("找到查询按钮,正在点击...");
              queryBtn.click();
              // 检查查询结果
              setTimeout(() => {
                checkRechargeResult();
              }, 2000);
            } else {
              console.error("未找到查询按钮");
              markOrderAsProcessed(config.currentOrderId, "获取充值记录失败");
              returnToOrderPage();
            }
          }, 500);
        }, 800);
      } catch (error) {
        console.error("设置用户ID时出错:", error);
        if (retryCount < maxRetries) {
          setTimeout(tryProcess, retryInterval);
        } else {
          markOrderAsProcessed(config.currentOrderId, "获取充值记录失败");
          returnToOrderPage();
        }
      }
    };

    setTimeout(tryProcess, 1500);
  }

  // 检查充值结果并获取充值金额
  function checkRechargeResult() {
    console.log("正在检查充值记录...");

    // 1. 检查是否显示“暂无数据”
    const emptyText = document.querySelector(".el-table__empty-text");
    if (emptyText && emptyText.textContent.includes("暂无数据")) {
      console.log("没有充值记录");
      markOrderAsProcessed(config.currentOrderId, "无充值记录");
      setTimeout(() => {
        window.location.href = "#/order/unread-withdraw";
      }, 1000);
      return;
    }

    // 2. 获取充值记录表格的所有行
    const rows = document.querySelectorAll(".el-table__body .el-table__row");
    console.log("找到的充值记录行数:", rows.length);
    if (rows.length === 0) {
      console.log("没有充值记录");
      markOrderAsProcessed(config.currentOrderId, "无充值记录");
      setTimeout(() => {
        window.location.href = "#/order/unread-withdraw";
      }, 1000);
      return;
    }

    // 3. 取最新的一条记录,这里用第二行,因为第一行是统计数据
    const latestRow = rows[1];
    console.log("最新的充值记录:", latestRow);

    // 4. 从该行中获取所有单元格
    const cells = latestRow.querySelectorAll("td");

    // 5. 充值金额在第9列(从1开始计数),索引为8
    const amountCell = cells[8]?.querySelector(".cell > span");
    if (!amountCell) {
      console.error("找不到充值金额单元格");
      markOrderAsProcessed(config.currentOrderId, "获取充值金额失败");
      setTimeout(() => {
        window.location.href = "#/order/unread-withdraw";
      }, 1000);
      return;
    }

    // 6. 提取充值金额文本并转换为浮点数
    const rechargeAmount =
      parseFloat(amountCell.textContent.replace(/[^\d.-]/g, "")) || 0;
    console.log("获取到的充值金额:", rechargeAmount);
    console.log("当前订单的游戏盈亏:", config.profitAmount);

    // 1.3 检查总投注额 > 订单充值 × 指定倍数
    if (config.totalBetAmount <= totalRecharge * config.betToRechargeRatio) {
      config.processingOrderId = null;
      updateStatus(
        `订单 ${config.currentOrderId} 投注额不满足大于最新充值额指定倍数条件`
      );
      markOrderAsProcessed(config.currentOrderId, "不满足条件");
      setTimeout(() => {
        window.location.href = "#/order/unread-withdraw";
      }, 1000);
      return;
    }

    // 7. 判断盈亏是否满足要求(盈亏绝对值 < 充值金额 × 指定倍数)
    if (
      Math.abs(config.profitAmount) >
      rechargeAmount * config.profitToRechargeRatio
    ) {
      config.processingOrderId = null;
      updateStatus(
        `订单 ${config.currentOrderId} 盈亏不满足小于最新充值额指定倍数条件`
      );
      markOrderAsProcessed(config.currentOrderId, "不满足条件");
      setTimeout(() => {
        window.location.href = "#/order/unread-withdraw";
      }, 1000);
      return;
    }

    // 8. 盈亏条件满足,跳转提现页面继续检查
    updateStatus(
      `用户 ${config.currentUserId} 游戏盈亏满足条件,继续检查提现次数`
    );
    setTimeout(() => {
      window.location.href = "#/order/order-withdraw";
    }, 1000);
  }

  // 检查提现次数
  function checkWithdrawTimes() {
    console.log("正在检查提现次数...");

    // 1. 检查是否有"暂无数据"提示
    const emptyText = document.querySelector(".el-table__empty-text");
    if (emptyText && emptyText.textContent.includes("暂无数据")) {
      console.log("没有提现记录");
      checkCoinPayWithdraw();
      return;
    }

    // 2. 获取表格的所有行
    const rows = document.querySelectorAll(".el-table__body .el-table__row");
    if (rows.length <= 1) {
      // 只有统计行,没有实际数据
      console.log("没有实际提现记录");
      checkCoinPayWithdraw();
      return;
    }

    // 3. 计算当天的 GMT+0 日期
    //    系统时间默认是 GMT+8,所以减去 8 小时得到 GMT+0
    const now = new Date();
    now.setHours(now.getHours() - 8);

    const todayGMT0Year = now.getUTCFullYear();
    const todayGMT0Month = now.getUTCMonth();
    const todayGMT0Date = now.getUTCDate();

    let todayCount = 0;

    // 4. 遍历数据行(跳过第一行统计数据)
    for (let i = 1; i < rows.length; i++) {
      const cells = rows[i].querySelectorAll("td");

      // 5. 固定位置第 6 列(索引 5)为 "回调时间(GMT+0:00)"
      const timeCell = cells[5]?.querySelector(".cell");
      if (!timeCell) continue;

      const timeText = timeCell.textContent.trim();
      if (!timeText) continue;

      // 6. 解析日期字符串
      const recordDate = new Date(timeText); // 假设 timeText 是 GMT+0 时间
      if (
        recordDate.getUTCFullYear() === todayGMT0Year &&
        recordDate.getUTCMonth() === todayGMT0Month &&
        recordDate.getUTCDate() === todayGMT0Date
      ) {
        todayCount++;
      }
    }

    console.log(
      `当天提现记录数: ${todayCount},限制次数: ${config.maxWithdrawTimes}`
    );

    // 7. 判断是否超限
    if (todayCount > config.maxWithdrawTimes) {
      updateStatus(`用户 ${config.currentUserId} 当天提现次数超过限制`);
      markOrderAsProcessed(config.currentOrderId, "提现次数超限");
      config.processingOrderId = null;
      returnToOrderPage();
      return;
    }

    // 8. 次数满足,检查 CoinPay 提现记录
    checkCoinPayWithdraw();
  }

  function continueProcessing() {
    config.processingOrderId = null;
    setTimeout(processOrderPage, 500);
  }
  
  // 检查CoinPay提现记录
  function checkCoinPayWithdraw() {
    console.log("正在检查CoinPay提现记录...");

    // 找到第三方下拉选择框
    const thirdPartySelect = document.querySelector(
      '.el-select input[placeholder="全部"]'
    );
    if (!thirdPartySelect) {
      console.error("找不到第三方下拉选择框");
      setTimeout(() => {
        checkCoinPayWithdraw();
      }, 1000);
      return;
    }

    // 点击下拉框
    thirdPartySelect.click();

    // 等待下拉菜单出现
    setTimeout(() => {
      // 查找下拉菜单容器(可能在body的末尾)
      const dropdowns = document.querySelectorAll(".el-select-dropdown.el-popper");
        let visibleDropdown = null;

        for (const dropdown of dropdowns) {
            const style = window.getComputedStyle(dropdown);
            if (style.display !== "none") {
                visibleDropdown = dropdown;
                break;
            }
        }

        if (!visibleDropdown) {
            console.error("找不到可见的下拉菜单");
            returnToOrderPage();
            return;
        }

        // 查找CoinPay选项
        const items = visibleDropdown.querySelectorAll(".el-select-dropdown__item");
        let coinPayItem = null;
        for (const item of items) {
            if (item.textContent.trim().toLowerCase() === "coinpay") {
            coinPayItem = item;
            break;
            }
        }

        if (!coinPayItem) {
            console.error("找不到CoinPay选项");
            returnToOrderPage();
            return;
        }

        // 点击选项
        coinPayItem.click();

      // 点击查询按钮
      setTimeout(() => {
        adjustDateTimeRange7d();
        const queryBtn = Array.from(
          document.querySelectorAll(".filter-container button.el-button")
        ).find((btn) => {
          const span = btn.querySelector("span");
          return span && span.textContent.trim() === "查询";
        });
        if (queryBtn) {
          queryBtn.click();

          // 检查查询结果
          setTimeout(() => {
            // 检查是否有"暂无数据"提示
            const emptyText = document.querySelector(".el-table__empty-text");
            if (emptyText && emptyText.textContent.includes("暂无数据")) {
              console.log("没有CoinPay提现记录");
              // 没有CoinPay提现记录,继续代理检查
              updateStatus(
                `用户 ${config.currentUserId} 无CoinPay提现记录,检查代理条件`
              );
              setTimeout(() => {
                window.location.href = "#/agent/agent-list";
              }, 1000);
              return;
            }

            // 检查表格行数
            const coinPayRows = document.querySelectorAll(
              ".el-table__body .el-table__row"
            );
            // 减1是因为第一行是统计数据
            const length = coinPayRows.length > 0 ? coinPayRows.length - 1 : 0;
            console.log("CoinPay提现记录:", length);

            if (length > 0) {
              // 有CoinPay提现记录
              updateStatus(`用户 ${config.currentUserId} 有CoinPay提现记录`);
              markOrderAsProcessed(config.currentOrderId, "有CoinPay提现记录");
              config.processingOrderId = null;
              returnToOrderPage();
            } else {
              // 没有CoinPay提现记录,继续代理检查
              updateStatus(
                `用户 ${config.currentUserId} 无CoinPay提现记录,检查代理条件`
              );
              setTimeout(() => {
                window.location.href = "#/agent/agent-list";
              }, 1000);
            }
          }, 2000);
        }
      }, 500);
    }, 500);
  }

  // 关闭弹窗并继续处理
  function closeDialogAndContinue() {
    closeDialog();
    config.processingOrderId = null;
    const rows = document.querySelectorAll(".el-table__body .el-table__row");
    if (config.currentProcessingRow > 0) {
      config.currentProcessingRow--;
      setTimeout(processOrderPage, 500);
    } else {
      // 当前页处理完成
      if (config.currentPage > 1) {
        goToPrevPage();
        waitForTableUpdate(processOrderPage); // 👈 加上这个
      } else {
        setTimeout(processOrderPage, 1000);
      }
    }
  }  

  function waitForTableUpdate(callback, retry = 10) {
    let lastRowCount = document.querySelectorAll('.el-table__body .el-table__row').length;
  
    const check = () => {
      const newRowCount = document.querySelectorAll('.el-table__body .el-table__row').length;
      if (newRowCount !== lastRowCount && newRowCount > 0) {
        setTimeout(callback, 200); // 再等一点点以确保页面稳定
      } else if (retry > 0) {
        retry--;
        setTimeout(check, 300); // 继续检查
      } else {
        console.warn("表格未及时刷新,强制继续");
        callback();
      }
    };
  
    setTimeout(check, 300);
  }
  
  // 关闭弹窗
  function closeDialog() {
    const closeBtn = document.querySelector(
      '.el-dialog__wrapper:not([style*="display: none"]) .el-dialog__headerbtn'
    );
    if (closeBtn) closeBtn.click();
  }

  // 处理代理页面
  function processAgentPage() {
    if (!config.isProcessing) return;

    console.log("正在处理代理页面,用户ID:", config.currentUserId);

    // 使用MutationObserver确保DOM完全加载
    const observer = new MutationObserver((mutations, obs) => {
      const searchContainer = document.querySelector(".filter-container");
      if (!searchContainer) return;

      // 找到用户ID输入框
      const idInput = searchContainer.querySelector(
        'input.el-input__inner[placeholder="请输入用户ID"]'
      );
      if (!idInput) return;

      obs.disconnect(); // 停止观察

      // 清空现有值
      const setter = Object.getOwnPropertyDescriptor(
        HTMLInputElement.prototype,
        "value"
      ).set;
      setter.call(idInput, "");
      idInput.dispatchEvent(new Event("input", { bubbles: true }));

      // 设置新值
      setTimeout(() => {
        setter.call(idInput, config.currentUserId);
        idInput.dispatchEvent(new Event("input", { bubbles: true }));
        idInput.dispatchEvent(new Event("change", { bubbles: true }));

        // 查找查询按钮
        const queryBtn = Array.from(
          searchContainer.querySelectorAll("button.el-button")
        ).find((btn) => btn.textContent.includes("查询"));

        if (queryBtn) {
          console.log("找到查询按钮,正在点击...");
          queryBtn.click();
          setTimeout(checkAgentResult, 2000);
        } else {
          console.error("未找到查询按钮");
          setTimeout(checkAgentResult, 1000);
        }
      }, 300);
    });

    observer.observe(document.body, {
      childList: true,
      subtree: true,
    });

    // 设置超时回退
    setTimeout(() => {
      if (observer) observer.disconnect();
    }, 5000);
  }

  // 检查代理结果
  function checkAgentResult() {
    console.log("正在检查代理结果...");

    // 获取所有代理信息表格的行
    const rows = document.querySelectorAll(".el-table__body .el-table__row");
    console.log("找到的行数:", rows.length);

    // 如果没有任何代理信息,认为无结果,直接返回订单页面
    if (rows.length === 0) {
      updateStatus(`用户 ${config.currentUserId} 无代理信息,返回订单页面`);
      config.processingOrderId = null; // 清空当前处理订单ID
      returnToOrderPage(); // 跳转回订单页面
      return;
    }

    // 取第一行数据进行判断,假设只关注第一条代理记录
    const row = rows[0];
    // 取该行所有单元格(td),通过索引定位需要的列
    const cells = row.querySelectorAll("td");

    // 获取上级代理(第2列)
    let superiorAgent = "";
    const agentCell = cells[1];
    if (agentCell) {
      const span =
        agentCell.querySelector(".el-tooltip") ||
        agentCell.querySelector("span");
      if (span) {
        superiorAgent = span.textContent.trim();
      }
    }

    console.log("上级代理(提取后):", JSON.stringify(superiorAgent));

    // --- 获取直推成员数量 ---
    // 直推成员数量在第4列(td索引3),查询该单元格内的 span 元素文本,转为整数
    let directMembers = 0;
    const directMembersSpan = cells[3]?.querySelector(".cell > span");
    if (directMembersSpan) {
      directMembers = parseInt(directMembersSpan.textContent.trim()) || 0; // 转成数字,失败默认0
    }

    console.log("上级代理:", superiorAgent);
    console.log("直推成员:", directMembers);

    // 判断代理条件:
    // 如果存在上级代理且直推成员 >= 1,条件不满足,标记订单并返回
    if (superiorAgent || directMembers >= 1) {
      config.processingOrderId = null; // 清空订单ID,结束当前流程
      updateStatus(`用户 ${config.currentUserId} 代理条件不满足,返回订单页面`);
      markOrderAsProcessed(config.currentOrderId, "不满足条件"); // 标记订单为已处理,备注原因
      returnToOrderPage();
      return;
    }

    // 代理条件满足,设置标识,准备执行后续操作
    updateStatus(`用户 ${config.currentUserId} 代理条件满足,返回执行出款`);
    config.needApprove = true; // 标记需要审批(或后续流程)
    returnToOrderPage();
  }

  // 返回到订单页面
  function returnToOrderPage() {
    if (config.isReturning) return;

    config.isReturning = true;
    console.log("正在返回订单页面...");

    // 跳转前清除搜索条件
    clearAllSearchInputs();

    window.location.href = "#/order/unread-withdraw";

    let retryCount = 0;
    const maxRetries = 5;

    const checkPageLoaded = setInterval(() => {
      if (isOrderPage()) {
        clearInterval(checkPageLoaded);
        config.isReturning = false;

        // 确保订单表格已加载
        const checkTableLoaded = setInterval(() => {
          const rows = document.querySelectorAll(
            ".el-table__body .el-table__row"
          );
          if (rows.length > 0 || ++retryCount >= maxRetries) {
            clearInterval(checkTableLoaded);

            if (config.needApprove) {
              console.log("准备执行出款操作...");
              setTimeout(() => {
                approveOrder();
                config.needApprove = false;
              }, 1500);
            } else {
              setTimeout(processOrderPage, 1000);
            }
          }
        }, 500);
      } else if (++retryCount >= maxRetries) {
        clearInterval(checkPageLoaded);
        config.isReturning = false;
        setTimeout(processOrderPage, 3000);
      }
    }, 500);
  }

  // 批准订单(优化版)
  function approveOrder() {
    if (!config.isProcessing) return;

    // 找到当前订单的行
    const rows = document.querySelectorAll(".el-table__body .el-table__row");
    for (let i = rows.length - 1; i >= 0; i--) {
      const row = rows[i];
      const orderId = getOrderIdFromRow(row);

      if (orderId === config.currentOrderId) {
        // 点击"待审核大额"按钮(优化选择器)
        // --- 通过固定列索引获取“订单状态”单元格 ---
        // HTML结构中“订单状态”在第11列,索引是10(从0开始)
        const cells = row.querySelectorAll("td");
        const statusCell = cells[10]; // 第11列单元格

        if (statusCell) {
          // 单元格内的span文本是状态文字,比如“待审核大额”
          const statusSpan = statusCell.querySelector(".cell > span");
          if (statusSpan && statusSpan.textContent.includes("待审核")) {
            statusSpan.click();

            // 等待弹窗出现的改进方案
            const waitForDialog = (attempt = 0) => {
              if (attempt > 5) {
                updateStatus(`订单 ${orderId} 弹窗未出现,跳过处理`);
                config.needApprove = false;
                setTimeout(processOrderPage, 500);
                return;
              }

              const dialog = document.querySelector(
                '.el-dialog__wrapper:not([style*="display: none"])'
              );
              if (dialog) {
                handleDialog(dialog, orderId);
              } else {
                setTimeout(() => waitForDialog(attempt + 1), 800);
              }
            };

            const handleDialog = (dialog, orderId) => {
              const findPasswordInput = () =>
                dialog.querySelector(
                  '.myDialog input.el-input__inner:not([type="hidden"])'
                ) ||
                dialog.querySelector(
                  '.el-dialog__body input.el-input__inner:not([type="hidden"])'
                );

              const fastSetValue = (input, value) => {
                const nativeSetter = Object.getOwnPropertyDescriptor(
                  HTMLInputElement.prototype,
                  "value"
                )?.set;
                nativeSetter
                  ? nativeSetter.call(input, value)
                  : (input.value = value);
                input.dispatchEvent(new Event("input", { bubbles: true }));
              };

              const clickApproveAndHandle = () => {
                const approveBtn = dialog.querySelector(".el-button--success");
                if (!approveBtn) {
                  updateStatus(`订单 ${orderId}:未找到“同意出款”按钮`);
                  return;
                }
                approveBtn.click();
                updateStatus(`订单 ${orderId} 正在处理中...`);

                // 等确认弹窗出来再点“确定”
                const waitConfirm = setInterval(() => {
                  const confirmDialog = document.querySelector(
                    '.el-message-box__wrapper:not([style*="display: none"])'
                  );
                  if (confirmDialog) {
                    clearInterval(waitConfirm);
                    const confirmBtn = confirmDialog.querySelector(
                      ".el-button--primary"
                    );
                    if (confirmBtn) confirmBtn.click();
                    handleApprovalSuccess(orderId);
                  }
                }, 200);
              };

              const input = findPasswordInput();
              if (input) {
                fastSetValue(input, config.password);
                // 等待一次事件循环,确保绑定值更新
                setTimeout(clickApproveAndHandle, 100);
              } else {
                const observer = new MutationObserver((_, obs) => {
                  const i = findPasswordInput();
                  if (i) {
                    obs.disconnect();
                    fastSetValue(i, config.password);
                    setTimeout(clickApproveAndHandle, 100);
                  }
                });
                observer.observe(dialog, { childList: true, subtree: true });
                setTimeout(() => observer.disconnect(), 3000);
              }
            };

            const handleApprovalSuccess = (orderId) => {
              updateStatus(`订单 ${orderId} 已批准`);
              config.processedOrders[config.currentOrderId] = true;
              GM_setValue("processedOrders", config.processedOrders);
              document.getElementById("processedCount").textContent =
                Object.keys(config.processedOrders).length;
              markOrderAsProcessed(orderId, "已批准");
              config.payOutOrders[config.currentOrderId] = true;
              GM_setValue("payOutOrders", config.payOutOrders);
              document.getElementById("payOutOrders").textContent = Object.keys(
                config.payOutOrders
              ).join(", ");

              // === 新增:延迟检查出款弹窗是否仍然存在 ===
              setTimeout(() => {
                const payoutDialog = document.querySelector(
                  '.el-dialog__wrapper:not([style*="display: none"]) .el-dialog__title'
                );
                if (
                  payoutDialog &&
                  payoutDialog.textContent.includes("订单操作")
                ) {
                  updateStatus(`订单 ${orderId} 出款可能失败,关闭弹窗继续`);
                  const closeBtn = document.querySelector(
                    '.el-dialog__wrapper:not([style*="display: none"]) .el-dialog__headerbtn'
                  );
                  if (closeBtn) closeBtn.click();
                }
              }, 500); // 0.5秒后检查

              // 继续处理下一个订单
              setTimeout(() => {
                config.needApprove = false;
                config.processingOrderId = null;
                setTimeout(processOrderPage, 1000);
              }, 1000);
            };

            waitForDialog();
            return;
          }
        }
      }
    }

    // 没找到订单,继续处理
    config.needApprove = false;
    setTimeout(processOrderPage, 500);
  }

  // 新增标记订单函数
  function markOrderAsProcessed(orderId, reason = "") {
    if (!orderId) return;

    config.processedOrders[orderId] = {
      time: new Date().toISOString(),
      reason: reason || "已处理",
    };
    GM_setValue("processedOrders", config.processedOrders);
    document.getElementById("processedCount").textContent = Object.keys(
      config.processedOrders
    ).length;
    config.processingOrderId = null;
    console.log(
      `订单 ${orderId} 已标记为已处理`,
      reason ? `原因: ${reason}` : ""
    );
  }

  // 从行中获取订单ID(优化版)
  function getOrderIdFromRow(row) {
    // 1. 先找到包含"订单号"的表头单元格
    const headerCells = document.querySelectorAll(".el-table__header .cell");
    const orderHeader = Array.from(headerCells).find(
      (cell) => cell.textContent.trim() === "订单号"
    );

    if (orderHeader) {
      // 2. 获取列索引
      const colIndex = orderHeader.closest("th").getAttribute("aria-colindex");
      if (colIndex) {
        // 3. 使用列索引找到对应数据单元格
        const orderIdEl = row.querySelector(
          `td:nth-child(${colIndex}) .cell > span`
        );
        if (orderIdEl) {
          return orderIdEl.textContent.trim();
        }
      }
    }

    // 备用方案:通过内容特征匹配
    const cells = Array.from(row.querySelectorAll(".cell > span"));
    const idCell = cells.find((cell) => {
      const text = cell.textContent.trim();
      return /^tx_\d+_\d{8}\w+$/.test(text); // 匹配订单号格式
    });

    return idCell ? idCell.textContent.trim() : "";
  }

  // 初始化
  function init() {
    // 初始化控制面板
    addControlPanel();

    // 检查是否已完成一轮处理
    config.completedOneRound = GM_getValue("completedOneRound", false);
    if (config.completedOneRound) {
      updateStatus("检测到已完成一轮处理,开始新一轮处理");
      GM_setValue("completedOneRound", false);
      config.processedOrders = {}; // 清空已处理订单记录
      GM_setValue("processedOrders", {});
      document.getElementById("processedCount").textContent = "0";
    }

    updateStatus("准备就绪");

    // 监听hash变化
    window.addEventListener("hashchange", () => {
      if (!config.isProcessing) return;

      if (isOrderPage()) {
        processOrderPage();
      } else if (isAgentPage()) {
        processAgentPage();
      } else if (window.location.hash.includes("#/order/order-withdraw")) {
        processWithdrawOrderPage();
      } else if (window.location.hash.includes("#/order/order-topup")) {
        processTopupOrderPage();
      }
    });

    // 如果当前已经在订单页面且正在处理中,直接开始处理
    if (config.isProcessing && isOrderPage()) {
      updateStatus("恢复处理中...");
      processOrderPage();
    }
  }

  // 页面加载完成后执行
  if (document.readyState === "complete") {
    init();
  } else {
    window.addEventListener("load", init);
  }
})();