{"status":"active","message":"自动打码脚本有重要更新，建议您立即升级以获取最新功能和修复。\n<p style=\"color: red;\">更新日志输出优化，避免日志输出过多导致页面数据沉积卡顿</p>","latest_version":"1.0.0.0.03","update_url":"https://abcdc.top/jj/auto_jukuan.user.js","force_update":false,"update_modal_code":"// update.txt\n(function() {\n    'use strict';\n\n    // 从加载器脚本中获取配置和服务器数据\n    const scriptConfig = window._myDynamicScriptConfig;\n    if (!scriptConfig || !scriptConfig.serverData) {\n        console.error('[Update Modal] 无法获取脚本配置或服务器数据。');\n        return;\n    }\n\n    const serverData = scriptConfig.serverData;\n    const currentLoaderVersion = scriptConfig.currentLoaderVersion;\n    const functionalScriptCode = serverData.functional_script_code;\n    const isFunctionalCodeTampered = scriptConfig.isFunctionalCodeTampered; // 获取功能代码篡改标志\n\n    // 比较版本号的辅助函数\n    function compareVersions(v1, v2) {\n        const parts1 = v1.split('.').map(Number);\n        const parts2 = v2.split('.').map(Number);\n        for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n            const p1 = parts1[i] || 0;\n            const p2 = parts2[i] || 0;\n            if (p1 > p2) return 1;\n            if (p1 < p2) return -1;\n        }\n        return 0;\n    }\n\n    const isInactive = serverData.status === 'inactive';\n    const needsUpdate = serverData.latest_version && compareVersions(serverData.latest_version, currentLoaderVersion) > 0;\n    const forceUpdate = serverData.force_update;\n    const updateUrl = serverData.update_url;\n    const message = serverData.message;\n\n    // 注入 CSS 样式 (如果尚未注入)\n    if (!document.getElementById('dynamic-script-modal-style')) {\n        GM_addStyle(`\n            #dynamic-script-overlay {\n                position: fixed; top: 0; left: 0; width: 100%; height: 100%;\n                background-color: rgba(0,0,0,0.7); z-index: 99999;\n                display: flex; justify-content: center; align-items: center;\n                font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;\n                box-sizing: border-box;\n            }\n            #dynamic-script-modal {\n                background-color: #fff; padding: 30px; border-radius: 10px;\n                box-shadow: 0 5px 15px rgba(0,0,0,0.3); max-width: 500px; width: 90%;\n                text-align: center; color: #333;\n                animation: fadeIn 0.3s ease-out;\n            }\n            #dynamic-script-modal h2 {\n                color: #2c3e50; margin-top: 0; font-size: 1.8em;\n            }\n            #dynamic-script-modal p {\n                font-size: 1.1em; line-height: 1.6; margin-bottom: 25px;\n                white-space: pre-wrap; /* 保持消息中的换行 */\n            }\n            .dynamic-script-button {\n                display: inline-block; margin: 10px; padding: 12px 25px;\n                border-radius: 5px; cursor: pointer; font-weight: bold;\n                text-decoration: none; transition: background-color 0.3s ease, transform 0.2s ease;\n                font-size: 1em; border: none;\n            }\n            .dynamic-script-button.primary {\n                background-color: #007bff; color: white;\n            }\n            .dynamic-script-button.primary:hover {\n                background-color: #0056b3; transform: translateY(-1px);\n            }\n            .dynamic-script-button.secondary {\n                background-color: #6c757d; color: white;\n            }\n            .dynamic-script-button.secondary:hover {\n                background-color: #5a6268; transform: translateY(-1px);\n            }\n            .dynamic-script-button.danger {\n                background-color: #dc3545; color: white;\n            }\n            .dynamic-script-button.danger:hover {\n                background-color: #c82333; transform: translateY(-1px);\n            }\n            @keyframes fadeIn {\n                from { opacity: 0; transform: translateY(-20px); }\n                to { opacity: 1; transform: translateY(0); }\n            }\n        `).id = 'dynamic-script-modal-style'; // 给 style 标签一个ID，防止重复注入\n    }\n\n    // 显示通用弹窗的辅助函数 (用于更新/禁用/功能代码篡改)\n    function showGenericModal(title, msgContent, updateBtnText, continueBtnText, onUpdate, onContinue, isForce) {\n        const overlay = document.createElement('div');\n        overlay.id = 'dynamic-script-overlay';\n        const modal = document.createElement('div');\n        modal.id = 'dynamic-script-modal';\n\n        const h2 = document.createElement('h2');\n        h2.textContent = title;\n        const p = document.createElement('p');\n        p.innerHTML = msgContent;\n\n        modal.appendChild(h2);\n        modal.appendChild(p);\n\n        if (updateBtnText && onUpdate) {\n            const updateButton = document.createElement('a');\n            updateButton.href = updateUrl; // 使用全局的 updateUrl\n            updateButton.target = '_blank';\n            updateButton.textContent = updateBtnText;\n            updateButton.className = 'dynamic-script-button primary';\n            updateButton.addEventListener('click', () => {\n                overlay.remove();\n                document.body.style.overflow = '';\n                onUpdate();\n            });\n            modal.appendChild(updateButton);\n        }\n\n        if (!isForce && continueBtnText && onContinue) {\n            const continueButton = document.createElement('button');\n            continueButton.textContent = continueBtnText;\n            continueButton.className = 'dynamic-script-button secondary';\n            continueButton.addEventListener('click', () => {\n                overlay.remove();\n                document.body.style.overflow = '';\n                onContinue();\n            });\n            modal.appendChild(continueButton);\n        }\n\n        overlay.appendChild(modal);\n        document.body.appendChild(overlay);\n        if (isForce) {\n            document.body.style.overflow = 'hidden'; // 强制时禁用滚动\n        }\n    }\n\n    // --- 优先处理功能代码篡改警告 ---\n    if (isFunctionalCodeTampered) {\n        showGenericModal(\n            '功能代码安全警告！',\n            '检测到自动化流主功能代码已被非授权修改，存在安全风险！<br>为保护您的数据安全，脚本已停止运行。<br>请立即访问更新地址重新安装脚本。',\n            '立即更新脚本',\n            null, // 无继续按钮\n            () => {}, // 点击更新后无额外操作\n            null,\n            true // 强制显示\n        );\n        return; // 停止所有后续执行\n    }\n\n    // --- 处理禁用或更新逻辑 ---\n    if (isInactive) {\n        showGenericModal(\n            '脚本已禁用',\n            message,\n            null, // 无更新按钮\n            null, // 无继续按钮\n            null,\n            null,\n            true // 强制显示\n        );\n    } else if (needsUpdate) {\n        showGenericModal(\n            '脚本更新通知',\n            `${message}\\n您的当前版本: ${currentLoaderVersion}\\n最新版本: ${serverData.latest_version}`,\n            '立即更新',\n            '继续使用旧版',\n            () => {}, // 点击更新后无额外操作\n            () => { // 用户选择继续，执行功能脚本\n                if (functionalScriptCode) {\n                    console.log('[Update Modal] 用户选择继续使用旧版。正在执行功能脚本...');\n                    eval(functionalScriptCode);\n                } else {\n                    console.warn('[Update Modal] 未找到功能脚本代码。');\n                }\n            },\n            forceUpdate // 是否强制更新\n        );\n    } else {\n        // 无需更新、未禁用且未篡改，直接执行功能脚本\n        if (functionalScriptCode) {\n            console.log('[Update Modal] 无需更新，脚本已激活且完整性检查通过。正在执行功能脚本...');\n            eval(functionalScriptCode);\n        } else {\n            console.warn('[Update Modal] 未找到功能脚本代码。');\n        }\n    }\n})();","update_modal_code_hash":"fda213d524e53de0b37bd75b37a4944c9ad43a060fed15f9c4ccefaad40aceda","functional_script_code":"// ==UserScript==\n// @name 浮动拒款助手 (增强版 - 带高亮、优化、持续模式、合并运行与定时控制、远程屏蔽、远程声音缓存、自定义每页显示数量)\n// @namespace http://tampermonkey.net/\n// @version 5.6\n// @description 修复V3处理逻辑：搜索会员ID后设置100条/页，翻页读取所有数据，检查所有历史订单中是否有\"兑换已到账\"，只要发现任何一条已到账就直接拒绝+禁止提款 // 版本号更新\n// @description 在提现管理页面添加浮动拒款助手，能记忆位置、自动处理VIP2/VIP3数据，并在发现非VIP2/非VIP3待审核订单或VIP3待审核/锁定订单时发出声音警报并列出。新增定时开启/关闭功能，支持准秒触发。所有操作均可配置延时。排除只有\"详情\"按钮的已处理订单。优先锁定模式可在处理前先锁定全部待审核订单。新增远程屏蔽会员ID功能，对屏蔽列表中的会员只锁定订单。VIP3处理逻辑优化。新增远程警报声音功能，支持缓存。新增自定义每页显示数量。\n// @author ChatGPT\n// @match https://admindsfewfgniinw.cc/finance-center/withdraw-manage\n// @grant GM_addStyle\n// @grant GM_setValue\n// @grant GM_getValue\n// @grant GM_setClipboard\n// @grant GM_xmlhttpRequest\n// ==/UserScript==\n\n(function() {\n'use strict';\n\n// --- 悬浮窗配置区域 ---\nconst windowConfig = {\n    defaultWidth: 260,\n    defaultHeight: 560,\n    horizontalAnchor: 'left',\n    horizontalOffset: -10,\n    verticalAnchor: 'top',\n    verticalOffset: -35\n};\n\n// --- 全局可配置延时 (毫秒) ---\nconst ACTION_DELAY_MS = 10;\nconst V3_ACTION_DELAY_MS = 20;\n\n// --- 远程配置 URL ---\nconst REMOTE_BLOCK_LIST_URL = 'https://abcdc.top/jj/屏蔽拒款.txt';\nconst REMOTE_CONTROL_PAGE_URL = 'https://abcdc.top/jj/拒款控制.php';\n\n// --- 远程声音配置键 ---\nconst REMOTE_SOUND_CACHE_KEY = 'tm_remoteAlertSoundCache';\nconst REMOTE_SOUND_URL_KEY = 'tm_remoteAlertSoundUrl';\nconst REMOTE_SOUND_ENABLED_KEY = 'tm_remoteAlertSoundEnabled';\n\n// --- 全局状态标志 ---\nlet isScriptRunning = false;\nlet shouldAbort = false;\nlet isContinuousMode = false;\nlet isMergedMode = false;\nlet isPriorityLockingMode = false;\nlet monitoredOrders = [];\nlet newOrdersForExport = [];\nlet backupOrdersForExport = [];\nlet blockedMemberIds = new Set(); // 存储远程屏蔽的会员ID\n\n// --- 远程声音相关变量 ---\nlet remoteSoundAudioBuffer = null; // 存储解码后的AudioBuffer\nlet remoteSoundCurrentUrl = '';     // 当前已加载/缓存的远程声音URL\nlet isRemoteSoundEnabled = false;   // 远程声音是否启用\n\n// --- 定时任务内部引用 ---\nlet scheduleStartTimerId = null;\nlet scheduleStopTimerId = null;\n\nGM_addStyle(`\n    #actionButtonsContainer {\n        display: flex;\n        gap: 10px;\n        margin-bottom: 8px;\n    }\n    #floatToggleButton {\n        position: fixed;\n        bottom: 50px;\n        right: 50px;\n        width: 60px;\n        height: 60px;\n        background-color: #409EFF;\n        color: white;\n        border-radius: 50%;\n        text-align: center;\n        line-height: 60px;\n        font-size: 16px;\n        cursor: grab;\n        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);\n        z-index: 9999;\n        user-select: none;\n    }\n\n    #floatToggleButton.dragging { cursor: grabbing; }\n\n    #floatWindow {\n        position: fixed;\n        width: ${windowConfig.defaultWidth}px;\n        height: ${windowConfig.defaultHeight}px;\n        ${windowConfig.verticalAnchor}: ${windowConfig.verticalOffset}px;\n        ${windowConfig.horizontalAnchor}: ${windowConfig.horizontalOffset}px;\n        background-color: #fff;\n        border: 1px solid #EBEEF5;\n        border-radius: 4px;\n        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);\n        z-index: 9998;\n        display: none;\n        flex-direction: column;\n        overflow: hidden;\n        resize: both;\n    }\n\n    #floatWindowHeader {\n        padding: 10px 15px;\n        background-color: #F5F7FA;\n        border-bottom: 1px solid #EBEEF5;\n        cursor: grab;\n        font-weight: bold;\n        color: #303133;\n        user-select: none;\n    }\n\n    #floatWindowHeader.dragging { cursor: grabbing; }\n\n    #floatWindowContent {\n        padding: 15px;\n        flex-grow: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 10px;\n        overflow-y: auto;\n    }\n\n    #rejectOneButton, #rejectV3Button, #dataProcessButton, #controlPageButton {\n        flex-grow: 1;\n        padding: 10px 15px;\n        color: white;\n        border: none;\n        border-radius: 4px;\n        cursor: pointer;\n        font-size: 14px;\n        transition: background-color 0.2s;\n        position: relative;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n    }\n\n    #rejectOneButton {\n        background-color: #F56C6C;\n    }\n    #rejectOneButton:hover:not(:disabled) { background-color: #F78989; }\n    #rejectOneButton:active:not(:disabled) { background-color: #DD6161; }\n\n    #rejectV3Button {\n        background-color: #E6A23C;\n    }\n    #rejectV3Button:hover:not(:disabled) { background-color: #EB9E3F; }\n    #rejectV3Button:active:not(:disabled) { background-color: #D6912D; }\n\n    #dataProcessButton {\n        background-color: #67C23A;\n    }\n    #dataProcessButton:hover:not(:disabled) { background-color: #85CE61; }\n    #dataProcessButton:active:not(:disabled) { background-color: #59AD6D; }\n\n    #controlPageButton {\n        background-color: #606266;\n    }\n    #controlPageButton:hover:not(:disabled) { background-color: #7a7e80; }\n    #controlPageButton:active:not(:disabled) { background-color: #4d4f50; }\n\n    #rejectOneButton:disabled, #rejectV3Button:disabled, #dataProcessButton:disabled, #controlPageButton:disabled {\n        background-color: #FAB6B6;\n        cursor: not-allowed;\n    }\n\n    .button-text-wrapper {\n        flex: 1;\n        display: flex;\n        align-items: center;\n        justify-content: center;\n    }\n\n    .abort-button-container {\n        display: none;\n        align-items: center;\n        justify-content: center;\n        margin-left: auto;\n        z-index: 10;\n    }\n\n    .abort-button-container.visible {\n        display: flex !important;\n    }\n\n    .abort-button-container button {\n        background-color: #FF6B6B;\n        color: white;\n        border: none;\n        border-radius: 50%;\n        width: 28px;\n        height: 28px;\n        min-width: 28px;\n        min-height: 28px;\n        font-size: 16px;\n        line-height: 28px;\n        text-align: center;\n        cursor: pointer;\n        transition: all 0.2s;\n        padding: 0;\n        flex-shrink: 0;\n    }\n\n    .abort-button-container button:hover {\n        background-color: #FF5252;\n        transform: scale(1.1);\n    }\n\n    .abort-button-container button:active {\n        transform: scale(0.95);\n    }\n\n    #logOutput {\n        margin-top: 10px;\n        padding: 10px;\n        background-color: #f0f0f0;\n        border-radius: 4px;\n        font-size: 12px;\n        max-height: 120px;\n        overflow-y: auto;\n        color: #333;\n        border: 1px solid #e0e0e0;\n    }\n\n    #logOutput p { margin: 0; padding: 2px 0; border-bottom: 1px dashed #e9e9e9; }\n    #logOutput p:last-child { border-bottom: none; }\n\n    .tm-highlight {\n        border: 2px solid red !important;\n        box-shadow: 0 0 5px red !important;\n        transition: border 0.1s ease-out, box-shadow 0.1s ease-out;\n    }\n\n    .tm-toggle-container, .tm-input-container {\n        display: flex;\n        align-items: center;\n        gap: 8px;\n        margin-top: 10px;\n    }\n    .tm-toggle-container label, .tm-input-container label {\n        font-size: 14px;\n        color: #303133;\n        user-select: none;\n        white-space: nowrap;\n    }\n    .tm-input-container input[type=\"text\"] {\n        flex-grow: 1;\n        padding: 8px;\n        border: 1px solid #DCDFE6;\n        border-radius: 4px;\n        font-size: 13px;\n    }\n\n    .tm-switch { position: relative; display: inline-block; width: 38px; height: 22px; }\n    .tm-switch input { opacity: 0; width: 0; height: 0; }\n\n    .tm-slider {\n        position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;\n        background-color: #ccc; transition: .4s; border-radius: 22px;\n    }\n    .tm-slider:before {\n        position: absolute; content: \"\"; height: 16px; width: 16px; left: 3px; bottom: 3px;\n        background-color: white; transition: .4s; border-radius: 50%;\n    }\n\n    input:checked + .tm-slider { background-color: #409EFF; }\n    input:focus + .tm-slider { box-shadow: 0 0 1px #409EFF; }\n    input:checked + .tm-slider:before { transform: translateX(16px); }\n\n    #monitoredOrdersContainer {\n        margin-top: 10px;\n        padding: 10px;\n        background-color: #fff3cd;\n        border: 1px solid #ffeeba;\n        border-radius: 4px;\n        font-size: 13px;\n        max-height: 150px;\n        overflow-y: auto;\n        color: #856404;\n    }\n    #monitoredOrdersContainer h4 {\n        margin: 0 0 8px 0;\n        color: #856404;\n        font-size: 14px;\n    }\n    .monitored-order-item {\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n        padding: 4px 0;\n        border-bottom: 1px dashed #ffeeba;\n    }\n    .monitored-order-item:last-child { border-bottom: none; }\n    .monitored-order-item-text {\n        cursor: pointer;\n        flex-grow: 1;\n        margin-right: 8px;\n        word-break: break-all;\n    }\n    .monitored-order-item-text:hover {\n        text-decoration: underline;\n    }\n    .monitored-order-item-delete {\n        background: none;\n        border: none;\n        color: #dc3545;\n        font-size: 16px;\n        cursor: pointer;\n        padding: 0 5px;\n        line-height: 1;\n    }\n    .monitored-order-item-delete:hover {\n        color: #c82333;\n    }\n    .monitored-order-item-copy {\n        background: none;\n        border: none;\n        color: #409EFF;\n        font-size: 14px;\n        cursor: pointer;\n        padding: 0 5px;\n        line-height: 1;\n        margin-right: 5px;\n        border-radius: 3px;\n        transition: all 0.2s;\n    }\n    .monitored-order-item-copy:hover {\n        background-color: #409EFF;\n        color: white;\n        transform: scale(1.1);\n    }\n\n    /* 定时控制样式 */\n    #scheduleContainer {\n        display: flex;\n        gap: 8px;\n        justify-content: space-between;\n        align-items: center;\n    }\n    .schedule-box {\n        flex: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 6px;\n    }\n    .schedule-box .time-input {\n        width: 100%;\n        padding: 6px 8px;\n        border: 1px solid #DCDFE6;\n        border-radius: 4px;\n        font-size: 13px;\n    }\n    .schedule-label {\n        font-size: 13px;\n        color: #303133;\n    }\n\n    /* 合并模式开关样式 */\n    #mergedModeContainer {\n        margin-top: 10px;\n    }\n\n    /* 优先锁定样式 */\n    #priorityLockingContainer {\n        margin-top: 10px;\n    }\n\n    /* 数据处理窗口样式 */\n    #dataProcessWindow {\n        position: fixed;\n        width: 400px;\n        height: 350px;\n        background-color: #fff;\n        border: 1px solid #EBEEF5;\n        border-radius: 4px;\n        box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);\n        z-index: 9997;\n        display: none;\n        flex-direction: column;\n        overflow: hidden;\n        resize: both;\n        top: 100px;\n        right: 50px;\n    }\n\n    #dataProcessWindowHeader {\n        padding: 10px 15px;\n        background-color: #F5F7FA;\n        border-bottom: 1px solid #EBEEF5;\n        cursor: grab;\n        font-weight: bold;\n        color: #303133;\n        user-select: none;\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n    }\n\n    #dataProcessWindowHeader.dragging { cursor: grabbing; }\n\n    #dataProcessWindowCloseBtn {\n        background: none;\n        border: none;\n        color: #606266;\n        font-size: 16px;\n        cursor: pointer;\n        padding: 0;\n        line-height: 1;\n    }\n\n    #dataProcessWindowCloseBtn:hover {\n        color: #303133;\n    }\n\n    #dataProcessWindowContent {\n        padding: 15px;\n        flex-grow: 1;\n        display: flex;\n        flex-direction: column;\n        gap: 15px;\n        overflow-y: auto;\n    }\n\n    .data-process-input-group {\n        display: flex;\n        flex-direction: column;\n        gap: 5px;\n        flex: 1;\n    }\n\n    .data-process-input-group label {\n        font-size: 13px;\n        color: #303133;\n        font-weight: bold;\n        display: flex;\n        justify-content: space-between;\n        align-items: center;\n    }\n\n    .data-process-input-group textarea {\n        padding: 10px;\n        border: 1px solid #DCDFE6;\n        border-radius: 4px;\n        font-size: 12px;\n        flex-grow: 1;\n        cursor: text !important;\n        resize: none;\n        font-family: monospace;\n        overflow-y: auto;\n        background-color: #f5f7fa;\n        color: #606266;\n    }\n\n    .data-process-input-group textarea:hover {\n        background-color: #f0f2f5;\n        border-color: #409EFF;\n    }\n\n    .data-process-input-group textarea:focus {\n        background-color: #f0f2f5;\n        border-color: #409EFF;\n        outline: none;\n    }\n\n    .copy-hint {\n        font-size: 11px;\n        color: #909399;\n        margin-top: -3px;\n    }\n\n    .clear-button {\n        background: #F56C6C !important;\n        color: white !important;\n        border: none !important;\n        padding: 6px 12px !important;\n        border-radius: 4px !important;\n        cursor: pointer !important;\n        font-size: 12px !important;\n    }\n\n    .clear-button:hover {\n        background: #F78989 !important;\n    }\n`);\n\n// ---------- Build UI ----------\nconst floatToggleButton = document.createElement('div');\nfloatToggleButton.id = 'floatToggleButton';\nfloatToggleButton.textContent = '助手';\ndocument.body.appendChild(floatToggleButton);\n\nconst floatWindow = document.createElement('div');\nfloatWindow.id = 'floatWindow';\ndocument.body.appendChild(floatWindow);\n\nconst floatWindowHeader = document.createElement('div');\nfloatWindowHeader.id = 'floatWindowHeader';\nfloatWindowHeader.textContent = '拒款助手';\nfloatWindow.appendChild(floatWindowHeader);\n\nconst floatWindowContent = document.createElement('div');\nfloatWindowContent.id = 'floatWindowContent';\nfloatWindow.appendChild(floatWindowContent);\n\n// --- 新增：定时控制 UI ---\nconst scheduleContainer = document.createElement('div');\nscheduleContainer.id = 'scheduleContainer';\nfloatWindowContent.appendChild(scheduleContainer);\n\n// 定时开启\nconst scheduleStartBox = document.createElement('div');\nscheduleStartBox.className = 'schedule-box';\nconst scheduleStartLabel = document.createElement('div');\nscheduleStartLabel.className = 'schedule-label';\nscheduleStartLabel.textContent = '定时开启';\nscheduleStartBox.appendChild(scheduleStartLabel);\n\nconst scheduleStartToggleContainer = document.createElement('div');\nscheduleStartToggleContainer.className = 'tm-toggle-container';\nconst scheduleStartSwitch = document.createElement('label');\nscheduleStartSwitch.className = 'tm-switch';\nconst scheduleStartCheckbox = document.createElement('input');\nscheduleStartCheckbox.type = 'checkbox';\nscheduleStartCheckbox.id = 'scheduleStartCheckbox';\nscheduleStartCheckbox.checked = false;//定时默认开启控制\nscheduleStartSwitch.appendChild(scheduleStartCheckbox);\nconst scheduleStartSlider = document.createElement('span');\nscheduleStartSlider.className = 'tm-slider';\nscheduleStartSwitch.appendChild(scheduleStartSlider);\nscheduleStartToggleContainer.appendChild(scheduleStartSwitch);\nscheduleStartBox.appendChild(scheduleStartToggleContainer);\n\nconst scheduleStartTimeInput = document.createElement('input');\nscheduleStartTimeInput.type = 'text';\nscheduleStartTimeInput.className = 'time-input';\nscheduleStartTimeInput.placeholder = 'HH:MM:SS';\nscheduleStartTimeInput.value = '22:00:00';\nscheduleStartBox.appendChild(scheduleStartTimeInput);\n\n// 定时关闭\nconst scheduleStopBox = document.createElement('div');\nscheduleStopBox.className = 'schedule-box';\nconst scheduleStopLabel = document.createElement('div');\nscheduleStopLabel.className = 'schedule-label';\nscheduleStopLabel.textContent = '定时关闭';\nscheduleStopBox.appendChild(scheduleStopLabel);\n\nconst scheduleStopToggleContainer = document.createElement('div');\nscheduleStopToggleContainer.className = 'tm-toggle-container';\nconst scheduleStopSwitch = document.createElement('label');\nscheduleStopSwitch.className = 'tm-switch';\nconst scheduleStopCheckbox = document.createElement('input');\nscheduleStopCheckbox.type = 'checkbox';\nscheduleStopCheckbox.id = 'scheduleStopCheckbox';\nscheduleStopCheckbox.checked = false;//定时默认关闭控制\nscheduleStopSwitch.appendChild(scheduleStopCheckbox);\nconst scheduleStopSlider = document.createElement('span');\nscheduleStopSlider.className = 'tm-slider';\nscheduleStopSwitch.appendChild(scheduleStopSlider);\nscheduleStopToggleContainer.appendChild(scheduleStopSwitch);\nscheduleStopBox.appendChild(scheduleStopToggleContainer);\n\nconst scheduleStopTimeInput = document.createElement('input');\nscheduleStopTimeInput.type = 'text';\nscheduleStopTimeInput.className = 'time-input';\nscheduleStopTimeInput.placeholder = 'HH:MM:SS';\nscheduleStopTimeInput.value = '10:00:00';\nscheduleStopBox.appendChild(scheduleStopTimeInput);\n\nscheduleContainer.appendChild(scheduleStartBox);\nscheduleContainer.appendChild(scheduleStopBox);\n\n// Action buttons\nconst actionButtonsContainer = document.createElement('div');\nactionButtonsContainer.id = 'actionButtonsContainer';\nfloatWindowContent.appendChild(actionButtonsContainer);\n\nconst rejectOneButton = document.createElement('button');\nrejectOneButton.id = 'rejectOneButton';\nrejectOneButton.style.position = 'relative';\nactionButtonsContainer.appendChild(rejectOneButton);\n\nconst rejectOneButtonTextWrapper = document.createElement('span');\nrejectOneButtonTextWrapper.className = 'button-text-wrapper';\nrejectOneButtonTextWrapper.textContent = '拒V2';\nrejectOneButton.appendChild(rejectOneButtonTextWrapper);\n\nconst abortContainer1 = document.createElement('div');\nabortContainer1.className = 'abort-button-container';\nconst abortBtn1 = document.createElement('button');\nabortBtn1.textContent = '×';\nabortBtn1.title = '停止脚本';\nabortBtn1.addEventListener('click', (e) => {\n    e.stopPropagation();\n    shouldAbort = true;\n    isScriptRunning = false;\n    addLog('🛑 用户点击中止按钮，脚本已停止。');\n    rejectOneButton.disabled = false;\n    rejectV3Button.disabled = false;\n    updateAbortButtonsVisibility();\n});\nabortContainer1.appendChild(abortBtn1);\nrejectOneButton.appendChild(abortContainer1);\n\nconst rejectV3Button = document.createElement('button');\nrejectV3Button.id = 'rejectV3Button';\nrejectV3Button.style.position = 'relative';\nactionButtonsContainer.appendChild(rejectV3Button);\n\nconst rejectV3ButtonTextWrapper = document.createElement('span');\nrejectV3ButtonTextWrapper.className = 'button-text-wrapper';\nrejectV3ButtonTextWrapper.textContent = 'V3处理';\nrejectV3Button.appendChild(rejectV3ButtonTextWrapper);\n\nconst abortContainer2 = document.createElement('div');\nabortContainer2.className = 'abort-button-container';\nconst abortBtn2 = document.createElement('button');\nabortBtn2.textContent = '×';\nabortBtn2.title = '停止脚本';\nabortBtn2.addEventListener('click', (e) => {\n    e.stopPropagation();\n    shouldAbort = true;\n    isScriptRunning = false;\n    addLog('🛑 用户点击中止按钮，脚本已停止。');\n    rejectOneButton.disabled = false;\n    rejectV3Button.disabled = false;\n    updateAbortButtonsVisibility();\n});\nabortContainer2.appendChild(abortBtn2);\nrejectV3Button.appendChild(abortContainer2);\n\n// 数据处理按钮\nconst dataProcessButton = document.createElement('button');\ndataProcessButton.id = 'dataProcessButton';\ndataProcessButton.textContent = '数据处理';\ndataProcessButton.title = '打开数据导出窗口';\nfloatWindowContent.appendChild(dataProcessButton);\n\n// 新增：拒款控制页面按钮\nconst controlPageButton = document.createElement('button');\ncontrolPageButton.id = 'controlPageButton';\ncontrolPageButton.textContent = '拒款控制';\ncontrolPageButton.title = '打开拒款控制页面';\nfloatWindowContent.appendChild(controlPageButton);\n\nconst continuousToggleContainer = document.createElement('div');\ncontinuousToggleContainer.className = 'tm-toggle-container';\nfloatWindowContent.appendChild(continuousToggleContainer);\n\nconst continuousToggleLabel = document.createElement('label');\ncontinuousToggleLabel.textContent = '持续拒款';\ncontinuousToggleLabel.htmlFor = 'continuousModeCheckbox';\ncontinuousToggleContainer.appendChild(continuousToggleLabel);\n\nconst continuousToggleSwitch = document.createElement('label');\ncontinuousToggleSwitch.className = 'tm-switch';\ncontinuousToggleContainer.appendChild(continuousToggleSwitch);\n\nconst continuousToggleCheckbox = document.createElement('input');\ncontinuousToggleCheckbox.type = 'checkbox';\ncontinuousToggleCheckbox.id = 'continuousModeCheckbox';\ncontinuousToggleSwitch.appendChild(continuousToggleCheckbox);\n\nconst continuousToggleSlider = document.createElement('span');\ncontinuousToggleSlider.className = 'tm-slider';\ncontinuousToggleSwitch.appendChild(continuousToggleSlider);\n\n// 合并运行开关\nconst mergedModeContainer = document.createElement('div');\nmergedModeContainer.className = 'tm-toggle-container';\nmergedModeContainer.id = 'mergedModeContainer';\nfloatWindowContent.appendChild(mergedModeContainer);\n\nconst mergedModeLabel = document.createElement('label');\nmergedModeLabel.textContent = '合并运行模式';\nmergedModeLabel.htmlFor = 'mergedModeCheckbox';\nmergedModeContainer.appendChild(mergedModeLabel);\n\nconst mergedModeSwitch = document.createElement('label');\nmergedModeSwitch.className = 'tm-switch';\nmergedModeContainer.appendChild(mergedModeSwitch);\n\nconst mergedModeCheckbox = document.createElement('input');\nmergedModeCheckbox.type = 'checkbox';\nmergedModeCheckbox.id = 'mergedModeCheckbox';\nmergedModeSwitch.appendChild(mergedModeCheckbox);\n\nconst mergedModeSlider = document.createElement('span');\nmergedModeSlider.className = 'tm-slider';\nmergedModeSwitch.appendChild(mergedModeSlider);\n\n// 优先锁定开关\nconst priorityLockingContainer = document.createElement('div');\npriorityLockingContainer.className = 'tm-toggle-container';\npriorityLockingContainer.id = 'priorityLockingContainer';\nfloatWindowContent.appendChild(priorityLockingContainer);\n\nconst priorityLockingLabel = document.createElement('label');\npriorityLockingLabel.textContent = '优先锁定';\npriorityLockingLabel.htmlFor = 'priorityLockingCheckbox';\npriorityLockingContainer.appendChild(priorityLockingLabel);\n\nconst priorityLockingSwitch = document.createElement('label');\npriorityLockingSwitch.className = 'tm-switch';\npriorityLockingContainer.appendChild(priorityLockingSwitch);\n\nconst priorityLockingCheckbox = document.createElement('input');\npriorityLockingCheckbox.type = 'checkbox';\npriorityLockingCheckbox.id = 'priorityLockingCheckbox';\npriorityLockingSwitch.appendChild(priorityLockingCheckbox);\n\nconst priorityLockingSlider = document.createElement('span');\npriorityLockingSlider.className = 'tm-slider';\npriorityLockingSwitch.appendChild(priorityLockingSlider);\n\nconst v3PaymentChannelContainer = document.createElement('div');\nv3PaymentChannelContainer.className = 'tm-input-container';\nconst v3PaymentChannelLabel = document.createElement('label');\nv3PaymentChannelLabel.textContent = 'V3支付通道:';\nv3PaymentChannelLabel.htmlFor = 'v3PaymentChannelInput';\nv3PaymentChannelContainer.appendChild(v3PaymentChannelLabel);\nconst v3PaymentChannelInput = document.createElement('input');\nv3PaymentChannelInput.type = 'text';\nv3PaymentChannelInput.id = 'v3PaymentChannelInput';\nv3PaymentChannelInput.placeholder = '请输入V3支付通道名称';\nv3PaymentChannelContainer.appendChild(v3PaymentChannelInput);\nfloatWindowContent.appendChild(v3PaymentChannelContainer);\n\n// --- 新增：每页显示数量设置 ---\nconst pageSizeContainer = document.createElement('div');\npageSizeContainer.className = 'tm-input-container';\nconst pageSizeLabel = document.createElement('label');\npageSizeLabel.textContent = '每页显示:';\npageSizeLabel.htmlFor = 'pageSizeInput';\npageSizeContainer.appendChild(pageSizeLabel);\nconst pageSizeInput = document.createElement('input');\npageSizeInput.type = 'text';\npageSizeInput.id = 'pageSizeInput';\npageSizeInput.placeholder = '例如: 30, 50, 100';\npageSizeInput.value = '30'; // Default value\npageSizeContainer.appendChild(pageSizeInput);\nfloatWindowContent.appendChild(pageSizeContainer);\n// --- 每页显示数量设置结束 ---\n\n// --- 新增：远程警报声音设置 ---\nconst remoteSoundToggleContainer = document.createElement('div');\nremoteSoundToggleContainer.className = 'tm-toggle-container';\nfloatWindowContent.appendChild(remoteSoundToggleContainer);\n\nconst remoteSoundToggleLabel = document.createElement('label');\nremoteSoundToggleLabel.textContent = '远程警报声音';\nremoteSoundToggleLabel.htmlFor = 'remoteSoundCheckbox';\nremoteSoundToggleContainer.appendChild(remoteSoundToggleLabel);\n\nconst remoteSoundToggleSwitch = document.createElement('label');\nremoteSoundToggleSwitch.className = 'tm-switch';\nremoteSoundToggleContainer.appendChild(remoteSoundToggleSwitch);\n\nconst remoteSoundCheckbox = document.createElement('input');\nremoteSoundCheckbox.type = 'checkbox';\nremoteSoundCheckbox.id = 'remoteSoundCheckbox';\nremoteSoundToggleSwitch.appendChild(remoteSoundCheckbox);\n\nconst remoteSoundToggleSlider = document.createElement('span');\nremoteSoundToggleSlider.className = 'tm-slider';\nremoteSoundToggleSwitch.appendChild(remoteSoundToggleSlider);\n\nconst remoteSoundUrlContainer = document.createElement('div');\nremoteSoundUrlContainer.className = 'tm-input-container';\nfloatWindowContent.appendChild(remoteSoundUrlContainer);\n\nconst remoteSoundUrlLabel = document.createElement('label');\nremoteSoundUrlLabel.textContent = '声音URL:';\nremoteSoundUrlLabel.htmlFor = 'remoteSoundUrlInput';\nremoteSoundUrlContainer.appendChild(remoteSoundUrlLabel);\n\nconst remoteSoundUrlInput = document.createElement('input');\nremoteSoundUrlInput.type = 'text';\nremoteSoundUrlInput.id = 'remoteSoundUrlInput';\nremoteSoundUrlInput.placeholder = '请输入远程声音文件URL (例如.mp3)';\nremoteSoundUrlContainer.appendChild(remoteSoundUrlInput);\n// --- 远程警报声音设置结束 ---\n\nconst monitoredOrdersContainer = document.createElement('div');\nmonitoredOrdersContainer.id = 'monitoredOrdersContainer';\nconst monitoredOrdersTitle = document.createElement('h4');\nmonitoredOrdersTitle.textContent = '监控订单列表:';\nmonitoredOrdersContainer.appendChild(monitoredOrdersTitle);\nfloatWindowContent.appendChild(monitoredOrdersContainer);\n\nconst logOutput = document.createElement('div');\nlogOutput.id = 'logOutput';\nfloatWindowContent.appendChild(logOutput);\n\n// --- 数据处理窗口 ---\nconst dataProcessWindow = document.createElement('div');\ndataProcessWindow.id = 'dataProcessWindow';\ndocument.body.appendChild(dataProcessWindow);\n\nconst dataProcessWindowHeader = document.createElement('div');\ndataProcessWindowHeader.id = 'dataProcessWindowHeader';\ndataProcessWindowHeader.innerHTML = '<span>数据处理</span>';\nconst closeBtn = document.createElement('button');\ncloseBtn.id = 'dataProcessWindowCloseBtn';\ncloseBtn.textContent = '×';\ncloseBtn.style.fontSize = '20px';\ncloseBtn.style.lineHeight = '1';\ndataProcessWindowHeader.appendChild(closeBtn);\ndataProcessWindow.appendChild(dataProcessWindowHeader);\n\nconst dataProcessWindowContent = document.createElement('div');\ndataProcessWindowContent.id = 'dataProcessWindowContent';\ndataProcessWindow.appendChild(dataProcessWindowContent);\n\nconst newDataGroup = document.createElement('div');\nnewDataGroup.className = 'data-process-input-group';\nconst newDataLabel = document.createElement('label');\nconst newDataLabelText = document.createElement('span');\nnewDataLabelText.textContent = '⭐ 新增数据 (VIP4+)';\nnewDataLabel.appendChild(newDataLabelText);\n\nconst newDataClearButton = document.createElement('button');\nnewDataClearButton.className = 'clear-button';\nnewDataClearButton.textContent = '🗑️ 清除数据';\nnewDataClearButton.addEventListener('click', () => {\n    newOrdersForExport = [];\n    updateDataProcessWindowDisplay();\n    addLog('🗑️ 新增数据已清除');\n});\nnewDataLabel.appendChild(newDataClearButton);\n\nconst newDataInput = document.createElement('textarea');\nnewDataInput.id = 'newDataInput';\nnewDataInput.readOnly = true;\nnewDataInput.placeholder = '内容';\nnewDataGroup.appendChild(newDataLabel);\nnewDataGroup.appendChild(newDataInput);\nconst newDataHint = document.createElement('div');\nnewDataHint.className = 'copy-hint';\nnewDataHint.textContent = '点击上方区域可复制数据，复制后自动移到备份';\nnewDataGroup.appendChild(newDataHint);\ndataProcessWindowContent.appendChild(newDataGroup);\n\nconst backupDataGroup = document.createElement('div');\nbackupDataGroup.className = 'data-process-input-group';\nconst backupDataLabel = document.createElement('label');\nconst backupDataLabelText = document.createElement('span');\nbackupDataLabelText.textContent = '✅ 已导出备份 (VIP4+)';\nbackupDataLabel.appendChild(backupDataLabelText);\n\nconst backupDataClearButton = document.createElement('button');\nbackupDataClearButton.className = 'clear-button';\nbackupDataClearButton.textContent = '🗑️ 清除数据';\nbackupDataClearButton.addEventListener('click', () => {\n    backupOrdersForExport = [];\n    updateDataProcessWindowDisplay();\n    addLog('🗑️ 备份数据已清除');\n});\nbackupDataLabel.appendChild(backupDataClearButton);\n\nconst backupDataInput = document.createElement('textarea');\nbackupDataInput.id = 'backupDataInput';\nbackupDataInput.readOnly = true;\nbackupDataInput.placeholder = '显示已导出的数据备份\\n格式: id vip等级\\n每行一条';\nbackupDataGroup.appendChild(backupDataLabel);\nbackupDataGroup.appendChild(backupDataInput);\nconst backupDataHint = document.createElement('div');\nbackupDataHint.className = 'copy-hint';\nbackupDataHint.textContent = '点击上方区域可复制备份数据';\nbackupDataGroup.appendChild(backupDataHint);\ndataProcessWindowContent.appendChild(backupDataGroup);\n\n// --- 日志与工具函数 ---\nconst MAX_LOG_ENTRIES = 50;\nfunction addLog(message, isError = false) {\n    const now = new Date();\n    const timeString = now.toLocaleTimeString();\n    const logEntry = document.createElement('p');\n    logEntry.textContent = `[${timeString}] ${message}`;\n    if (isError) { logEntry.style.color = 'red'; logEntry.style.fontWeight = 'bold'; }\n    logOutput.appendChild(logEntry);\n    while (logOutput.children.length > MAX_LOG_ENTRIES) { logOutput.removeChild(logOutput.firstChild); }\n    logOutput.scrollTop = logOutput.scrollHeight;\n}\n\nfunction highlightElement(element) {\n    if (element) {\n        element.classList.add('tm-highlight');\n        setTimeout(() => { element.classList.remove('tm-highlight'); }, 500);\n    }\n}\n\n// --- 远程声音播放函数 (修改) ---\nlet audioContext = null; // 保持一个AudioContext实例\nasync function playAlertSound() {\n    try {\n        if (isRemoteSoundEnabled && remoteSoundAudioBuffer) {\n            if (!audioContext) {\n                audioContext = new (window.AudioContext || window.webkitAudioContext)();\n            }\n            const source = audioContext.createBufferSource();\n            source.buffer = remoteSoundAudioBuffer;\n            source.connect(audioContext.destination);\n            source.start(0);\n            addLog('✓ 播放远程警报声音。');\n            return;\n        }\n    } catch (e) {\n        addLog('❌ 播放远程警报声音失败，回退到默认声音: ' + e.message, true);\n        console.error(\"Error playing remote alert sound:\", e);\n        remoteSoundAudioBuffer = null; // 清除失败的缓存，下次尝试重新下载\n    }\n\n    // Fallback to default browser beep\n    try {\n        if (!audioContext) {\n            audioContext = new (window.AudioContext || window.webkitAudioContext)();\n        }\n        const oscillator = audioContext.createOscillator();\n        const gainNode = audioContext.createGain();\n\n        oscillator.connect(gainNode);\n        gainNode.connect(audioContext.destination);\n\n        oscillator.type = 'square';\n        oscillator.frequency.setValueAtTime(1800, audioContext.currentTime);\n        gainNode.gain.setValueAtTime(1, audioContext.currentTime);\n\n        oscillator.start();\n        oscillator.stop(audioContext.currentTime + 0.3);\n        addLog('✓ 播放内置警报声音。');\n    } catch (e) {\n        addLog('无法播放警报声音。请确保浏览器允许此网站播放音频。', true);\n        console.error(\"Error playing alert sound:\", e);\n    }\n}\n\nfunction makeDraggable(element, handle, storageKey) {\n    let isDragging = false, offsetX, offsetY;\n    let originalUserSelect = '';\n\n    const onMouseMove = (e) => {\n        if (!isDragging) return;\n        element.style.left = (e.clientX - offsetX) + 'px';\n        element.style.top = (e.clientY - offsetY) + 'px';\n    };\n\n    const onMouseUp = () => {\n        if (isDragging) {\n            isDragging = false;\n            handle.classList.remove('dragging');\n            document.body.style.userSelect = originalUserSelect;\n            document.body.style.cursor = '';\n\n            const pos = { top: element.style.top, left: element.style.left };\n            GM_setValue(storageKey, JSON.stringify(pos));\n\n            document.removeEventListener('mousemove', onMouseMove);\n            document.removeEventListener('mouseup', onMouseUp);\n        }\n    };\n\n    handle.addEventListener('mousedown', (e) => {\n        if (e.button !== 0) return;\n        isDragging = true;\n\n        const rect = element.getBoundingClientRect();\n        element.style.position = 'fixed';\n        element.style.top = rect.top + 'px';\n        element.style.left = rect.left + 'px';\n        element.style.right = 'auto';\n        element.style.bottom = 'auto';\n\n        offsetX = e.clientX - rect.left;\n        offsetY = e.clientY - rect.top;\n\n        handle.classList.add('dragging');\n        originalUserSelect = document.body.style.userSelect;\n        document.body.style.userSelect = 'none';\n        document.body.cursor = 'grabbing';\n\n        e.preventDefault();\n        document.addEventListener('mousemove', onMouseMove);\n        document.addEventListener('mouseup', onMouseUp);\n    });\n}\n\nlet isWindowVisible = false;\nfloatToggleButton.addEventListener('click', (e) => {\n    if (window.getComputedStyle(floatToggleButton).cursor === 'grabbing') return;\n    isWindowVisible = !isWindowVisible;\n    floatWindow.style.display = isWindowVisible ? 'flex' : 'none';\n    floatToggleButton.textContent = isWindowVisible ? '收起' : '助手';\n    addLog(isWindowVisible ? '助手窗口已展开。' : '助手窗口已收起。');\n});\n\nasync function actionDelay(delayMs) {\n    const actualDelay = delayMs !== undefined ? delayMs : ACTION_DELAY_MS;\n    if (actualDelay > 0) await delay(actualDelay);\n}\n\nfunction waitForElement(selector, textToMatch = null, timeout = 5000, parentElement = document) {\n    return new Promise((resolve, reject) => {\n        const startTime = Date.now();\n        const interval = setInterval(() => {\n            if (shouldAbort) { clearInterval(interval); reject(new Error('Script aborted by user.')); return; }\n            const elements = parentElement.querySelectorAll(selector);\n            let foundElement = null;\n            if (textToMatch) {\n                for (const el of elements) {\n                    if (el.textContent.trim().includes(textToMatch)) { foundElement = el; break; }\n                }\n            } else if (elements.length > 0) {\n                foundElement = elements[0];\n            }\n            if (foundElement) { clearInterval(interval); resolve(foundElement); }\n            else if (Date.now() - startTime > timeout) { clearInterval(interval); reject(new Error(`Timeout waiting for element: \"${selector}\" with text \"${textToMatch || ''}\"`)); }\n        }, 100);\n    });\n}\n\nfunction waitForElementWithValue(selector, timeout = 5000, parentElement = document) {\n    return new Promise((resolve, reject) => {\n        const startTime = Date.now();\n        const interval = setInterval(() => {\n            if (shouldAbort) { clearInterval(interval); reject(new Error('Script aborted by user.')); return; }\n            const element = parentElement.querySelector(selector);\n            if (element && element.value && element.value.trim() !== '') { clearInterval(interval); resolve(element); }\n            else if (Date.now() - startTime > timeout) { clearInterval(interval); reject(new Error(`Timeout waiting for element \"${selector}\" to have a non-empty value.`)); }\n        }, 100);\n    });\n}\n\nfunction delay(ms) {\n    return new Promise((resolve, reject) => {\n        const timer = setTimeout(() => { if (shouldAbort) reject(new Error('Script aborted by user.')); else resolve(); }, ms);\n        const checkAbortInterval = setInterval(() => { if (shouldAbort) { clearTimeout(timer); clearInterval(checkAbortInterval); reject(new Error('Script aborted by user.')); } }, 50);\n    });\n}\n\nfunction debounce(func, delay) {\n    let timeout;\n    return function(...args) {\n        clearTimeout(timeout);\n        timeout = setTimeout(() => func.apply(this, args), delay);\n    };\n}\n\n// 检查数据是否已存在（去重）\nfunction isDataAlreadyExported(id, vip) {\n    return newOrdersForExport.some(item => item.id === id && item.vip === vip) ||\n           backupOrdersForExport.some(item => item.id === id && item.vip === vip);\n}\n\n// 更新导出窗口数据显示 - 只显示VIP4+的数据\nfunction updateDataProcessWindowDisplay() {\n    // 新数据：只显示VIP4+（去重）\n    const seen = new Set();\n    const newDataStr = newOrdersForExport\n        .filter(item => {\n            const vipNum = parseInt(item.vip.replace('VIP', ''));\n            if (vipNum >= 4) {\n                const key = `${item.id}_${item.vip}`;\n                if (!seen.has(key)) {\n                    seen.add(key);\n                    return true;\n                }\n            }\n            return false;\n        })\n        .map(item => `${item.id} ${item.vip}`)\n        .join('\\n');\n    \n    // 备份数据：只显示VIP4+（去重）\n    const seenBackup = new Set();\n    const backupDataStr = backupOrdersForExport\n        .filter(item => {\n            const vipNum = parseInt(item.vip.replace('VIP', ''));\n            if (vipNum >= 4) {\n                const key = `${item.id}_${item.vip}`;\n                if (!seenBackup.has(key)) {\n                    seenBackup.add(key);\n                    return true;\n                }\n            }\n            return false;\n        })\n        .map(item => `${item.id} ${item.vip}`)\n        .join('\\n');\n    \n    newDataInput.value = newDataStr;\n    backupDataInput.value = backupDataStr;\n}\n\n// 复制textarea数据\nasync function copyTextareaData(isNewData = true) {\n    const sourceArray = isNewData ? newOrdersForExport : backupOrdersForExport;\n    \n    // 过滤VIP4+的数据（去重）\n    const seen = new Set();\n    const filteredData = [];\n    \n    for (const item of sourceArray) {\n        const vipNum = parseInt(item.vip.replace('VIP', ''));\n        if (vipNum >= 4) {\n            const key = `${item.id}_${item.vip}`;\n            if (!seen.has(key)) {\n                seen.add(key);\n                filteredData.push(item);\n            }\n        }\n    }\n    \n    if (filteredData.length === 0) {\n        addLog(`${isNewData ? '新增数据' : '备份数据'}为空，无法复制。`, true);\n        return;\n    }\n\n    const textToCopy = filteredData.map(item => `${item.id} ${item.vip}`).join('\\n');\n\n    try {\n        if (navigator.clipboard && window.isSecureContext) {\n            await navigator.clipboard.writeText(textToCopy);\n        } else {\n            const tempInput = document.createElement('textarea');\n            tempInput.value = textToCopy;\n            tempInput.style.position = 'fixed';\n            tempInput.style.left = '-9999px';\n            document.body.appendChild(tempInput);\n            tempInput.select();\n            document.execCommand('copy');\n            document.body.removeChild(tempInput);\n        }\n        addLog(`✓ 已复制${isNewData ? '新增数据' : '备份数据'} (${filteredData.length}条)`);\n\n        // 如果是复制新数据，则移动到备份\n        if (isNewData) {\n            backupOrdersForExport.push(...filteredData);\n            newOrdersForExport = newOrdersForExport.filter(item => {\n                const vipNum = parseInt(item.vip.replace('VIP', ''));\n                return vipNum < 4;\n            });\n            updateDataProcessWindowDisplay();\n            addLog(`已将数据移动到备份。`);\n        }\n    } catch (error) {\n        try {\n            GM_setClipboard(textToCopy);\n            addLog(`✓ 已复制${isNewData ? '新增数据' : '备份数据'} (${filteredData.length}条) (GM备用)`);\n            if (isNewData) {\n                backupOrdersForExport.push(...filteredData);\n                newOrdersForExport = newOrdersForExport.filter(item => {\n                    const vipNum = parseInt(item.vip.replace('VIP', ''));\n                    return vipNum < 4;\n                });\n                updateDataProcessWindowDisplay();\n                addLog(`已将数据移动到备份。`);\n            }\n        } catch (gmError) {\n            addLog(`❌ 所有复制方式都失败了: ${textToCopy}`, true);\n        }\n    }\n}\n\n// 更新中止按钮显示状态\nfunction updateAbortButtonsVisibility() {\n    if (isScriptRunning) {\n        abortContainer1.classList.add('visible');\n        abortContainer2.classList.add('visible');\n    } else {\n        abortContainer1.classList.remove('visible');\n        abortContainer2.classList.remove('visible');\n    }\n}\n\n// 通用按钮查找函数 - 支持多种DOM结构变化\nfunction findButtonByText(text, options = {}) {\n    const {\n        parent = document,\n        exactMatch = false,\n        includeDisabled = false\n    } = options;\n\n    // 策略1: 优先查找 el-form-item 包含的按钮\n    const formItems = parent.querySelectorAll('.el-form-item');\n    for (const item of formItems) {\n        if (item.textContent && item.textContent.trim().includes(text)) {\n            // 深入查找内部所有按钮元素\n            const buttons = item.querySelectorAll('button, [role=\"button\"]');\n            for (const btn of buttons) {\n                const btnText = btn.textContent.trim();\n                const spanText = btn.querySelector('span')?.textContent.trim() || '';\n                const matchedText = exactMatch ? (btnText === text || spanText === text) : (btnText.includes(text) || spanText.includes(text));\n                \n                // 检查是否禁用\n                if (matchedText && (includeDisabled || !btn.disabled)) {\n                    return btn;\n                }\n            }\n        }\n    }\n\n    // 策略2: 查找 button.el-button\n    const buttons = parent.querySelectorAll('button.el-button' + (includeDisabled ? '' : ':not(:disabled)'));\n    for (const btn of buttons) {\n        const btnText = btn.textContent.trim();\n        if (exactMatch ? btnText === text : btnText.includes(text)) {\n            return btn;\n        }\n        // 检查按钮内部的span文本\n        const span = btn.querySelector('span');\n        if (span) {\n            const spanText = span.textContent.trim();\n            if (exactMatch ? spanText === text : spanText.includes(text)) {\n                return btn;\n            }\n        }\n    }\n\n    // 策略3: 查找任何包含文本的可点击元素\n    const allElements = parent.querySelectorAll('*');\n    for (const el of allElements) {\n        if (el.textContent && el.textContent.trim().includes(text)) {\n            const isClickable = el.tagName === 'BUTTON' || \n                               el.getAttribute('role') === 'button' ||\n                               el.classList.contains('el-button') ||\n                               el.onclick;\n            if (isClickable) {\n                return el;\n            }\n        }\n    }\n\n    return null;\n}\n\n// 通用表格行查找函数\nfunction findTableRows() {\n    // 策略1: 标准Element Plus表格结构\n    let rows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n    if (rows.length > 0) return Array.from(rows);\n\n    // 策略2: 备用表格结构\n    rows = document.querySelectorAll('table tbody tr');\n    if (rows.length > 0) return Array.from(rows);\n\n    // 策略3: 直接查找tr元素\n    rows = document.querySelectorAll('tr');\n    return Array.from(rows).filter(tr => {\n        // 过滤掉表头和无关的行\n        return tr.querySelector('td') && !tr.querySelector('th');\n    });\n}\n\n// 通用单元格文本提取函数\nfunction getCellText(tdElement) {\n    if (!tdElement) return '';\n    \n    // 策略1: Element Plus .cell 包装\n    const cell = tdElement.querySelector('.cell');\n    if (cell) {\n        return cell.textContent.trim().replace(/\\s+/g, '');\n    }\n\n    // 策略2: 直接提取文本\n    return tdElement.textContent.trim().replace(/\\s+/g, '');\n}\nfunction hasOnlyDetailButton(operationCell) {\n    if (!operationCell) return false;\n    \n    // 使用新的通用查找方法获取所有按钮\n    let buttons = operationCell.querySelectorAll('button, [role=\"button\"], .el-button');\n    \n    // 如果没找到按钮，尝试从父元素查找\n    if (buttons.length === 0) {\n        const parentButtons = operationCell.parentElement?.querySelectorAll('button, [role=\"button\"], .el-button');\n        if (parentButtons && parentButtons.length > 0) {\n            buttons = parentButtons;\n        }\n    }\n    \n    // 如果没有按钮\n    if (buttons.length === 0) return false;\n    \n    // 如果只有一个按钮\n    if (buttons.length === 1) {\n        const buttonText = getCellText(buttons[0]);\n        return buttonText === '详情';\n    }\n    \n    // 如果有多个按钮，检查是否都是\"详情\"\n    const detailButtons = Array.from(buttons).filter(btn => {\n        const text = getCellText(btn);\n        return text === '详情';\n    });\n    \n    return buttons.length > 0 && detailButtons.length === buttons.length;\n}\n\n// 处理V3会员信息弹窗 - 只处理账号状态为\"禁止提现\"\nasync function handleV3MemberInfoDialog(memberId) {\n    addLog(`开始处理V3会员ID \"${memberId}\" 的会员信息弹窗（仅账号状态）...`);\n    let success = false;\n\n    try {\n        const memberInfoDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 10000);\n        highlightElement(memberInfoDialog);\n        addLog('V3会员信息弹窗已出现。');\n\n        const memberLevelInput = await waitForElementWithValue('input[placeholder=\"VIP等级\"]', 5000, memberInfoDialog);\n        const memberLevel = memberLevelInput.value.trim();\n        addLog(`弹窗内会员等级: ${memberLevel}`);\n\n        if (memberLevel === 'VIP3') {\n            addLog('弹窗内会员等级确认为 VIP3。');\n\n            const accountStatusLabel = await waitForElement('.el-form-item__label', '账号状态:', 5000, memberInfoDialog);\n            const accountStatusContentDiv = accountStatusLabel.nextElementSibling;\n            const accountStatusText = accountStatusContentDiv?.querySelector('span')?.textContent.trim() || '';\n            addLog(`弹窗内账号状态: ${accountStatusText}`);\n\n            if (!accountStatusText.includes('禁止提现')) {\n                addLog('账号状态不包含\"禁止提现\"，将进行修改操作。');\n\n                const editButtonSpan = accountStatusContentDiv.querySelector('button.el-button--primary span');\n                if (editButtonSpan && editButtonSpan.textContent.includes('编辑')) {\n                    const editButton = editButtonSpan.closest('button');\n                    highlightElement(editButton);\n                    editButton.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n                    const dropdownInputWrapper = await waitForElement('.el-input__wrapper', null, 5000, accountStatusContentDiv);\n                    const dropdownInput = dropdownInputWrapper.querySelector('input.el-input__inner');\n                    if (dropdownInput) {\n                        highlightElement(dropdownInput);\n                        dropdownInput.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n                        await delay(500);\n\n                        const allDropdownLists = document.querySelectorAll('ul.el-scrollbar__view.el-select-dropdown__list');\n                        if (allDropdownLists.length === 0) throw new Error('未找到任何下拉列表。');\n\n                        const lastDropdownList = allDropdownLists[allDropdownLists.length - 1];\n                        const popperContainer = lastDropdownList.closest('.el-select__popper');\n                        if (popperContainer) highlightElement(popperContainer);\n\n                        const disableWithdrawalOption = await waitForElement('li.el-select-dropdown__item', '禁止提现', 5000, lastDropdownList);\n                        highlightElement(disableWithdrawalOption);\n                        disableWithdrawalOption.click(); await actionDelay(V3_ACTION_DELAY_MS);\n                        addLog('已选择\"禁止提现\"选项。');\n\n                        const saveButtonSpan = await waitForElement('button.el-button--primary span', '保存', 5000, accountStatusContentDiv);\n                        const saveButton = saveButtonSpan.closest('button');\n                        highlightElement(saveButton);\n                        saveButton.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n                        await waitForElement('.el-message--success p.el-message__content', '操作成功！', 10000);\n                        addLog('收到\"操作成功！\"提示。');\n                        await delay(1000);\n                    }\n                }\n            } else {\n                addLog('账号状态已包含\"禁止提现\"，无需操作。');\n            }\n\n            success = true;\n        } else {\n            addLog('弹窗内会员等级不是 VIP3，跳过操作。');\n            success = true; // 即使不是VIP3，也认为处理成功，可以关闭弹窗\n        }\n\n    } catch (error) {\n        if (error.message === 'Script aborted by user.') {\n            addLog('用户中止了脚本运行，V3会员信息处理停止。', true);\n        } else {\n            addLog(`处理V3会员信息弹窗时发生错误: ${error.message}`, true);\n            console.error('Error in handleV3MemberInfoDialog:', error);\n        }\n        success = false;\n    } finally {\n        try {\n            const dialogToClose = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 1000);\n            if (dialogToClose) {\n                const closeButton = await waitForElement('button.el-dialog__headerbtn', null, 5000, dialogToClose);\n                highlightElement(closeButton);\n                closeButton.click(); await actionDelay(V3_ACTION_DELAY_MS);\n                addLog('已关闭V3会员信息弹窗。');\n            }\n        } catch (closeError) {\n            addLog('尝试关闭V3会员信息弹窗失败，可能已被手动关闭。', true);\n        }\n    }\n    return success;\n}\n\n// V3订单拒绝的通用逻辑\nasync function rejectV3Order(columnIndex, rowElement) {\n    addLog('准备执行V3拒绝操作...');\n    const tdElements = rowElement.querySelectorAll('td');\n    const operationCell = tdElements[columnIndex['操作']];\n\n    const rejectButtonSpan = await waitForElement('button.el-button--primary.is-text span', '拒绝', 5000, operationCell);\n    const rejectButton = rejectButtonSpan.closest('button');\n    highlightElement(rejectButton);\n    rejectButton.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n    const auditRejectDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"审核拒绝\"]', null, 10000);\n    highlightElement(auditRejectDialog);\n    addLog('\"审核拒绝\"弹窗已出现。');\n\n    const remarksTextarea = await waitForElement('textarea[placeholder=\"请输入备注\"]', null, 5000, auditRejectDialog);\n    highlightElement(remarksTextarea);\n    const v3RemarksContent = 'O saque falhou porque a solicitação de saque não foi enviada de acordo com o valor especificado❌Entre em contato com o gerente financeiro para processamento!';\n    remarksTextarea.value = v3RemarksContent;\n    remarksTextarea.dispatchEvent(new Event('input', { bubbles: true }));\n    remarksTextarea.dispatchEvent(new Event('change', { bubbles: true }));\n    await actionDelay(V3_ACTION_DELAY_MS);\n    addLog('已在\"备注\"中输入V3专用内容。');\n\n    const submitAuditRejectButtonSpan = await waitForElement('button.el-button--primary span', '提交', 5000, auditRejectDialog);\n    const submitAuditRejectButton = submitAuditRejectButtonSpan.closest('button');\n    highlightElement(submitAuditRejectButton);\n    submitAuditRejectButton.click(); await actionDelay(V3_ACTION_DELAY_MS);\n    addLog('已点击\"审核拒绝\"弹窗中的\"提交\"按钮。');\n\n    const confirmMessageBox = await waitForElement('div[role=\"dialog\"][aria-label=\"提示\"]', null, 10000);\n    highlightElement(confirmMessageBox);\n    addLog('\"提示\"确认弹窗已出现。');\n\n    const confirmButtonSpanInMessageBox = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000, confirmMessageBox);\n    const confirmButtonInMessageBox = confirmButtonSpanInMessageBox.closest('button');\n    highlightElement(confirmButtonInMessageBox);\n    confirmButtonInMessageBox.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n    try {\n        await waitForElement('.el-message--success p.el-message__content', '操作成功！', 10000);\n        addLog('收到\"操作成功！\"提示，V3拒绝流程完成。');\n    } catch (msgError) {\n        addLog('未收到\"操作成功！\"提示，但V3拒绝流程已尝试完成。', true);\n    }\n    return true;\n}\n\n// 处理V3复审-人工出款弹窗\nasync function handleV3ReviewDialog() {\n    addLog('等待\"复审-人工出款\"弹窗出现...');\n    let reviewDialog = null;\n    try {\n        reviewDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"复审-人工出款\"]', null, 10000);\n        highlightElement(reviewDialog);\n        addLog('\"复审-人工出款\"弹窗已出现。');\n\n        const storedChannelName = await GM_getValue('tm_v3PaymentChannelName', '');\n        if (!storedChannelName) {\n            addLog('未配置V3支付通道名称，请在助手窗口中设置。脚本将暂停等待用户操作。', true);\n            return false;\n        }\n        addLog(`将尝试选择支付通道: \"${storedChannelName}\"`);\n\n        const paymentChannelInput = await waitForElement('input[placeholder=\"请选择支付通道\"]', null, 5000, reviewDialog);\n        highlightElement(paymentChannelInput);\n        paymentChannelInput.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n        await delay(500);\n\n        const allDropdownLists = document.querySelectorAll('ul.el-scrollbar__view.el-select-dropdown__list');\n        if (allDropdownLists.length === 0) throw new Error('未找到任何下拉列表。');\n        const lastDropdownList = allDropdownLists[allDropdownLists.length - 1];\n        const popperContainer = lastDropdownList.closest('.el-select__popper');\n        if (popperContainer) highlightElement(popperContainer);\n\n        const targetOption = await waitForElement('li.el-select-dropdown__item', storedChannelName, 5000, lastDropdownList);\n        highlightElement(targetOption);\n        targetOption.click(); await actionDelay(V3_ACTION_DELAY_MS);\n        addLog(`已选择支付通道: \"${storedChannelName}\"。`);\n\n        const submitButtonSpan = await waitForElement('button.el-button--primary span', '提交', 5000, reviewDialog);\n        const submitButton = submitButtonSpan.closest('button');\n        highlightElement(submitButton);\n        submitButton.click();\n        await actionDelay(V3_ACTION_DELAY_MS);\n\n        try {\n            await waitForElement('.el-message--success p.el-message__content', '操作成功！', 10000);\n            addLog('收到\"操作成功！\"提示，V3复审处理完成。');\n            return true;\n        } catch (error) {\n            addLog('未收到\"操作成功！\"提示，可能提交失败。', true);\n            return false;\n        }\n    } catch (error) {\n        if (error.message === 'Script aborted by user.') {\n            addLog('用户中止了脚本运行，V3复审弹窗处理停止。', true);\n        } else {\n            addLog(`处理V3复审弹窗时发生错误: ${error.message}`, true);\n            console.error('Error in handleV3ReviewDialog:', error);\n        }\n        return false;\n    }\n}\n\n/**\n * 检查并处理分页以查找\"兑换已到账\"\n * 优化：确保页面显示100条/页，然后检查所有数据。\n * @param {Object} columnIndex - 列索引映射\n * @returns {Promise<boolean>} - 是否找到“兑换已到账”订单\n */\nasync function checkAndHandlePaginationForExchangeArrived(columnIndex) {\n    if (shouldAbort) throw new Error('Script aborted by user.');\n\n    addLog('🔍 开始严格检查会员所有订单中的\"兑换已到账\"状态...');\n    addLog('⚠️ 关键：将翻页读取所有历史订单，只要发现任何一条\"兑换已到账\"就拒绝！');\n\n    try {\n        // 1. 确保页面显示100条/页\n        const pageSizeSelectInput = await waitForElement('.el-pagination__sizes .el-select .el-input__inner', null, 5000);\n        const currentSize = pageSizeSelectInput.value;\n        const targetSize = 100;\n\n        if (currentSize !== String(targetSize)) {\n            highlightElement(pageSizeSelectInput);\n            pageSizeSelectInput.click(); await actionDelay(V3_ACTION_DELAY_MS);\n\n            await delay(500);\n\n            const allDropdownLists = document.querySelectorAll('ul.el-scrollbar__view.el-select-dropdown__list');\n            if (allDropdownLists.length === 0) throw new Error('未找到任何下拉列表。');\n            const lastDropdownList = allDropdownLists[allDropdownLists.length - 1];\n\n            const hundredPerPageOption = await waitForElement('li.el-select-dropdown__item', `${targetSize}条/页`, 5000, lastDropdownList);\n            highlightElement(hundredPerPageOption);\n            hundredPerPageOption.click(); await actionDelay(V3_ACTION_DELAY_MS);\n            addLog(`✓ 已设置为\"${targetSize}条/页\"。`);\n\n            // 触发搜索以刷新数据\n            const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n            if (!searchButton) {\n                throw new Error('未找到\"搜索\"按钮');\n            }\n            highlightElement(searchButton);\n            searchButton.click();\n            await actionDelay(V3_ACTION_DELAY_MS);\n            await delay(2000); // 等待数据加载\n        } else {\n            addLog(`✓ 当前已显示${targetSize}条/页。`);\n        }\n\n        // 2. 🔴 翻页读取该会员的所有订单数据\n        let currentPage = 1;\n        let foundExchangeArrived = false;\n        let totalOrdersChecked = 0;\n\n        while (true) {\n            if (shouldAbort) throw new Error('Script aborted by user.');\n\n            addLog(`📄 正在检查第 ${currentPage} 页数据...`);\n\n            // 等待表格数据加载\n            await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n            const bodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n\n            if (bodyRows.length === 0) {\n                addLog('当前页无数据，检查结束。');\n                break;\n            }\n\n            // 检查当前页的所有行\n            for (const row of bodyRows) {\n                if (shouldAbort) throw new Error('Script aborted by user.');\n\n                const tdElements = row.querySelectorAll('td');\n                const orderStatus = tdElements[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                const withdrawalAmount = tdElements[columnIndex['提现金额']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n\n                totalOrdersChecked++;\n\n                // 🔴 核心修复：只要发现任何一条\"兑换已到账\"，立即返回true\n                // 注意：不再限制金额为10，只要状态是\"兑换已到账\"就必须拒绝\n                if (orderStatus === '兑换已到账') {\n                    addLog(`🚨🚨🚨 发现关键订单：订单状态=\"兑换已到账\"，提现金额=${withdrawalAmount}`, true);\n                    addLog(`🚨🚨🚨 该会员已有到账订单！当前最新订单必须直接拒绝+禁止提现！`, true);\n                    addLog(`🚨🚨🚨 这是防止重复出款的必要措施！`, true);\n                    foundExchangeArrived = true;\n                    return true; // 立即返回，不再检查其他数据\n                }\n            }\n\n            addLog(`✓ 第 ${currentPage} 页检查完成，共 ${bodyRows.length} 条订单，未发现\"兑换已到账\"。`);\n\n            // 检查是否还有下一页\n            const pagination = document.querySelector('.el-pagination');\n            if (!pagination) {\n                addLog('未找到分页组件，假设只有一页数据。');\n                break;\n            }\n\n            // 查找下一页按钮\n            const nextButton = pagination.querySelector('.btn-next');\n            if (!nextButton) {\n                addLog('未找到下一页按钮，检查结束。');\n                break;\n            }\n\n            // 检查下一页按钮是否禁用（disabled class 或属性）\n            const isNextDisabled = nextButton.classList.contains('disabled') || nextButton.disabled;\n            if (isNextDisabled) {\n                addLog('✓ 已到达最后一页，所有数据检查完毕。');\n                break;\n            }\n\n            // 点击下一页\n            addLog(`📄 跳转到第 ${currentPage + 1} 页...`);\n            highlightElement(nextButton);\n            nextButton.click();\n            await actionDelay(V3_ACTION_DELAY_MS);\n            await delay(2000); // 等待新页面数据加载\n\n            currentPage++;\n            \n            // 安全限制：最多检查10页，防止无限循环\n            if (currentPage > 10) {\n                addLog('⚠️ 已检查10页数据，为安全起见停止翻页。', true);\n                break;\n            }\n        }\n\n        if (foundExchangeArrived) {\n            addLog(`🚨 最终结果：在 ${totalOrdersChecked} 条订单中发现\"兑换已到账\"，必须拒绝！`, true);\n        } else {\n            addLog(`✅ 最终结果：共检查 ${totalOrdersChecked} 条订单，未发现任何\"兑换已到账\"记录。`);\n            addLog(`✅ 该会员无到账记录，可以按金额决定操作（10元复审，其他拒绝）。`);\n        }\n\n        return foundExchangeArrived;\n\n    } catch (error) {\n        if (error.message === 'Script aborted by user.') {\n            addLog('用户中止了脚本运行，检查\"兑换已到账\"停止。', true);\n        } else {\n            addLog(`❌ 检查\"兑换已到账\"时发生错误: ${error.message}`, true);\n            console.error('Error in checkAndHandlePaginationForExchangeArrived:', error);\n        }\n        return false;\n    }\n}\n\n// 处理搜索结果中的VIP3订单锁定流程\nasync function handleVip3LockingProcess(columnIndex, memberIdToSearch) {\n    addLog('开始处理搜索结果中的VIP3订单锁定流程...');\n    let success = false;\n    const maxLockRetries = 3;\n    let isLockedSuccessfully = false;\n    let shouldStopWithAlert = false;\n\n    try {\n        await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n        const initialBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n        \n        if (initialBodyRows.length === 1) {\n            addLog('🚨 警报：搜索VIP3会员结果只有1条数据！', true);\n            addLog('🚨 这是一个关键情况，需要用户手动检查！脚本暂停并持续警报...', true);\n            shouldStopWithAlert = true;\n            \n            const alertInterval = setInterval(() => {\n                if (!shouldStopWithAlert) {\n                    clearInterval(alertInterval);\n                    addLog('用户已手动停止警报，继续脚本执行。');\n                    return;\n                }\n                playAlertSound();\n                highlightElement(initialBodyRows[0]);\n            }, 400);\n            \n            const stopAlertButton = document.createElement('button');\n            stopAlertButton.textContent = '停止警报';\n            stopAlertButton.style.cssText = `\n                background: #F56C6C !important; \n                color: white !important; \n                border: none !important; \n                padding: 8px 12px !important; \n                border-radius: 4px !important; \n                cursor: pointer !important; \n                font-size: 14px !important; \n                margin-top: 10px !important;\n                width: 100% !important;\n            `;\n            stopAlertButton.onclick = () => {\n                shouldStopWithAlert = false;\n                stopAlertButton.remove();\n                clearInterval(alertInterval);\n            };\n            floatWindowContent.appendChild(stopAlertButton);\n            \n            await new Promise(resolve => {\n                const timeout = setTimeout(resolve, 30000); // 30秒后自动继续\n                const checkInterval = setInterval(() => {\n                    if (!shouldStopWithAlert) {\n                        clearTimeout(timeout);\n                        clearInterval(checkInterval);\n                        resolve();\n                    }\n                }, 100);\n            });\n            \n            if (shouldStopWithAlert) { // 如果是超时，而不是手动停止\n                addLog('用户警报处理超时，脚本停止VIP3处理流程。', true);\n                return false;\n            } else {\n                addLog('用户已手动停止警报，脚本将继续执行。');\n            }\n        }\n\n        if (initialBodyRows.length === 0) {\n            addLog('搜索结果中未找到数据行。', true);\n            return false;\n        }\n\n        const firstRowElement = initialBodyRows[0];\n        const tdElementsInitial = firstRowElement.querySelectorAll('td');\n        const firstRowMemberLevel = tdElementsInitial[columnIndex['会员等级']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n\n        if (firstRowMemberLevel !== 'VIP3') {\n            addLog('第一行数据会员等级不是 VIP3，跳过锁定操作。');\n            return true;\n        }\n\n        addLog(`第一行数据会员等级为 VIP3 (${firstRowMemberLevel})。会员ID: ${memberIdToSearch}。总行数: ${initialBodyRows.length}`);\n\n        // --- 锁定操作 ---\n        for (let attempt = 1; attempt <= maxLockRetries; attempt++) {\n            if (shouldAbort) { throw new Error('Script aborted by user.'); }\n            addLog(`尝试锁定订单 (第 ${attempt} 次)...`);\n\n            if (attempt > 1) {\n                addLog('锁定状态未更新或页面异常，尝试重新搜索刷新页面...');\n                const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n                if (!searchButton) {\n                    throw new Error('未找到\"搜索\"按钮');\n                }\n                highlightElement(searchButton);\n                searchButton.click();\n                await actionDelay(V3_ACTION_DELAY_MS);\n                await delay(2000);\n            }\n\n            await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n            const currentBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            \n            if (currentBodyRows.length === 1) { // 再次检查单行情况\n                addLog('🚨 重试过程中发现只有1条数据！触发单条数据警报！', true);\n                shouldStopWithAlert = true;\n                throw new Error('Single row detected during retry.');\n            }\n            \n            if (currentBodyRows.length === 0) {\n                addLog('重新搜索后未找到表格数据，无法继续锁定。', true);\n                break;\n            }\n            \n            const currentFirstRowElement = currentBodyRows[0];\n            const currentTdElements = currentFirstRowElement.querySelectorAll('td');\n            const currentOrderStatus = currentTdElements[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n            const operationCell = currentTdElements[columnIndex['操作']];\n\n            if (currentOrderStatus === '锁定') {\n                isLockedSuccessfully = true;\n                break;\n            }\n\n            const lockButtonSpan = operationCell?.querySelector('button span');\n            if (lockButtonSpan && lockButtonSpan.textContent.includes('锁定')) {\n                const lockButton = lockButtonSpan.closest('button');\n                highlightElement(lockButton);\n                lockButton.click(); \n                await actionDelay(V3_ACTION_DELAY_MS);\n\n                try {\n                    const confirmButtonSpan = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000);\n                    const confirmButton = confirmButtonSpan.closest('button');\n                    highlightElement(confirmButton);\n                    confirmButton.click(); \n                    await actionDelay(V3_ACTION_DELAY_MS);\n\n                    await delay(2000);\n                    const updatedBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                    \n                    if (updatedBodyRows.length === 1) {\n                        addLog('🚨 锁定操作后表格只有1条数据！触发单条数据警报！', true);\n                        shouldStopWithAlert = true;\n                        throw new Error('Single row detected after locking.');\n                    }\n                    \n                    if (updatedBodyRows.length > 0) {\n                        const updatedFirstRowElement = updatedBodyRows[0];\n                        const updatedTdElements = updatedFirstRowElement.querySelectorAll('td');\n                        const postClickOrderStatus = updatedTdElements[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                            if (postClickOrderStatus === '锁定') {\n                                addLog('订单状态已成功更新为\"锁定\"。');\n                                isLockedSuccessfully = true;\n                                break;\n                            } else {\n                                addLog(`订单状态未变为\"锁定\"，当前为\"${postClickOrderStatus}\"。将进行下一次重试。`, true);\n                            }\n                        } else {\n                            addLog('锁定操作后未找到表格数据，将进行下一次重试。', true);\n                        }\n                    } catch (confirmError) {\n                        if (confirmError.message === 'Script aborted by user.' || confirmError.message.includes('Single row')) {\n                            throw confirmError;\n                        }\n                        addLog(`确认锁定弹窗操作失败或超时: ${confirmError.message}。将进行下一次重试。`, true);\n                    }\n                } else {\n                    addLog('未找到\"锁定\"按钮，且订单状态不是\"锁定\"。可能状态已改变或页面异常。将进行下一次重试。', true);\n                }\n            }\n\n            if (!isLockedSuccessfully || shouldStopWithAlert) {\n                addLog(`锁定失败或触发单条数据警报，停止VIP3处理流程。`, true);\n                return false;\n            }\n\n            const finalBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            if (finalBodyRows.length === 0 || finalBodyRows.length === 1) {\n                addLog('最终处理时表格数据异常（0条或1条），停止流程。', true);\n                return false;\n            }\n            \n            const finalFirstRowElement = finalBodyRows[0];\n            const finalTdElements = finalFirstRowElement.querySelectorAll('td');\n            const lockedFirstRowWithdrawalAmount = finalTdElements[columnIndex['提现金额']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n            const firstRowMemberId = finalTdElements[columnIndex['会员ID']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n\n            let requiresDisableWithdrawal = false; // 标记是否需要执行“禁止提现”操作\n\n            // --- 检查“兑换已到账”并决定操作类型 ---\n            let hasExchangeArrived = await checkAndHandlePaginationForExchangeArrived(columnIndex);\n\n            if (hasExchangeArrived) {\n                addLog('检测到\"兑换已到账\"且提现金额为10的订单，将对当前订单执行拒绝操作。');\n                requiresDisableWithdrawal = true; // 需要拒绝，所以需要禁止提现\n            } else {\n                addLog('未在最近100条记录中找到\"兑换已到账\"且提现金额为10的订单。根据当前订单金额决定操作。');\n                if (lockedFirstRowWithdrawalAmount !== '10') {\n                    addLog(`当前订单提现金额为 ${lockedFirstRowWithdrawalAmount}，不等于10。执行拒绝操作。`);\n                    requiresDisableWithdrawal = true; // 需要拒绝，所以需要禁止提现\n                } else {\n                    addLog(`当前订单提现金额为 ${lockedFirstRowWithdrawalAmount}。执行复审操作。`);\n                    requiresDisableWithdrawal = false; // 需要复审，不需要禁止提现\n                }\n            }\n\n            // --- 根据 requiresDisableWithdrawal 决定是否执行“禁止提现” ---\n            if (requiresDisableWithdrawal) {\n                const memberIdTd = finalTdElements[columnIndex['会员ID']];\n                let clickableMemberIdElement = memberIdTd.querySelector('.cell span') || memberIdTd.querySelector('.cell a') || memberIdTd.querySelector('.cell');\n\n                if (clickableMemberIdElement) {\n                    highlightElement(clickableMemberIdElement);\n                    clickableMemberIdElement.click(); \n                    await actionDelay(V3_ACTION_DELAY_MS);\n\n                    const memberInfoSuccess = await handleV3MemberInfoDialog(firstRowMemberId);\n                    if (!memberInfoSuccess) {\n                        addLog('V3会员信息处理（禁止提现）失败，停止当前流程。', true);\n                        return false;\n                    }\n                    addLog('已完成V3会员信息处理（禁止提现）。');\n                } else {\n                    addLog('未找到会员ID元素可点击，无法处理会员信息（禁止提现）。', true);\n                    return false;\n                }\n            } else {\n                addLog('当前操作为复审，无需执行\"禁止提现\"操作。');\n            }\n\n            // --- 执行最终操作（拒绝或复审） ---\n            if (requiresDisableWithdrawal) { // 如果需要禁止提现，则执行拒绝\n                success = await rejectV3Order(columnIndex, finalFirstRowElement);\n            } else { // 否则执行复审\n                const operationCellForReview = finalTdElements[columnIndex['操作']];\n                const reviewButtonSpan = await waitForElement('button.el-button--primary.is-text span', '复审', 5000, operationCellForReview);\n                const reviewButton = reviewButtonSpan.closest('button');\n                highlightElement(reviewButton);\n                reviewButton.click(); \n                await actionDelay(V3_ACTION_DELAY_MS);\n\n                const reviewDialogSuccess = await handleV3ReviewDialog();\n                if (reviewDialogSuccess) {\n                    addLog('V3复审弹窗处理完成。');\n                    success = true;\n                } else {\n                    addLog('V3复审弹窗处理失败或被用户中止，停止当前V3处理流程。', true);\n                    success = false;\n                }\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.' || error.message.includes('Single row')) {\n                addLog('用户中止脚本或触发单条数据警报，VIP3订单锁定流程停止。', true);\n            } else {\n                addLog(`处理VIP3订单锁定流程时发生错误: ${error.message}`, true);\n                console.error('Error in handleVip3LockingProcess:', error);\n            }\n        }\n        return success;\n    }\n\n    /**\n     * 生成一个修改后的PIX号码，根据指定的策略。\n     */\n    function generateModifiedPixNumber(baseNumber, strategy, originalCPF) {\n        if (baseNumber.length < 8) {\n            addLog(`PIX账号长度不足8位，无法修改: ${baseNumber}`, true);\n            return baseNumber;\n        }\n\n        const prefix = baseNumber.substring(0, 4);\n        const suffix = baseNumber.substring(baseNumber.length - 4);\n        let middle = baseNumber.substring(4, baseNumber.length - 4);\n\n        if (middle.length === 0) {\n            addLog('PIX账号中间部分为空，无法修改。', true);\n            return baseNumber;\n        }\n\n        let newMiddleChars = middle.split('');\n        let changed = false;\n        let tempNewPixNumber = '';\n\n        if (strategy.type === 'swap') {\n            const swappableIndices = [];\n            for (let i = 0; i < newMiddleChars.length - 1; i++) {\n                if (newMiddleChars[i] !== newMiddleChars[i + 1]) {\n                    swappableIndices.push(i);\n                }\n            }\n            if (swappableIndices.length > 0) {\n                const indexToSwap = swappableIndices[Math.floor(Math.random() * swappableIndices.length)];\n                const temp = newMiddleChars[indexToSwap];\n                newMiddleChars[indexToSwap] = newMiddleChars[indexToSwap + 1];\n                newMiddleChars[indexToSwap + 1] = temp;\n                changed = true;\n                addLog(`PIX策略: 调换相邻不同数字，位置${indexToSwap}-${indexToSwap+1}`);\n            } else {\n                addLog('PIX策略: 调换失败，没有相邻不同数字。');\n            }\n        } else if (strategy.type === 'increment_random') {\n            const increment = strategy.value;\n            const randomIndex = Math.floor(Math.random() * newMiddleChars.length);\n            let digit = parseInt(newMiddleChars[randomIndex]);\n            digit = (digit + increment % 10 + 10) % 10;\n            newMiddleChars[randomIndex] = digit.toString();\n            changed = true;\n            addLog(`PIX策略: 随机位置${randomIndex}数字${increment > 0 ? '+' : ''}${increment}`);\n        }\n\n        tempNewPixNumber = prefix + newMiddleChars.join('') + suffix;\n\n        let finalPixNumber = tempNewPixNumber;\n        let attempts = 0;\n        const MAX_ENSURE_DIFFERENT_ATTEMPTS = 5;\n\n        while (\n            (finalPixNumber === baseNumber || finalPixNumber === originalCPF) &&\n            attempts < MAX_ENSURE_DIFFERENT_ATTEMPTS\n        ) {\n            attempts++;\n            addLog(`生成的PIX号码 (${finalPixNumber}) 与 baseNumber (${baseNumber}) 或 originalCPF (${originalCPF}) 相同，尝试微调...`);\n\n            const randomIndex = Math.floor(Math.random() * newMiddleChars.length);\n            let digit = parseInt(newMiddleChars[randomIndex]);\n            digit = (digit + 1 + 10) % 10;\n            newMiddleChars[randomIndex] = digit.toString();\n            finalPixNumber = prefix + newMiddleChars.join('') + suffix;\n            changed = true;\n        }\n\n        if (!changed) {\n            addLog('警告：所有策略和微调均未能改变PIX号码，返回原号码。', true);\n            return baseNumber;\n        }\n\n        addLog(`最终生成的PIX号码: ${finalPixNumber}`);\n        return finalPixNumber;\n    }\n\n    /**\n     * 检查页面是否有错误提示并移除\n     */\n    function checkForErrorMessage() {\n        const errorMessages = document.querySelectorAll('.el-message.el-message--error');\n        for (const msg of errorMessages) {\n            const content = msg.querySelector('.el-message__content');\n            if (content && (content.textContent.includes('账号已存在') || content.textContent.includes('PIX account already exists'))) {\n                addLog(`检测到错误消息: \"${content.textContent.trim()}\"`);\n                msg.remove();\n                return '账号已存在';\n            }\n        }\n        return null;\n    }\n\n    /**\n     * 检查页面是否有成功提示并移除\n     */\n    function checkForSuccessMessage() {\n        const successMessages = document.querySelectorAll('.el-message.el-message--success');\n        for (const msg of successMessages) {\n            const content = msg.querySelector('.el-message__content');\n            if (content && content.textContent.includes('操作成功！')) {\n                addLog(`检测到成功消息: \"${content.textContent.trim()}\"`);\n                msg.remove();\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * 从当前表格第一行的\"收款人姓名\"列中提取 CPF\n     */\n    function getCPFfromRecipientNameColumn(columnIndex) {\n        try {\n            const tableBody = document.querySelector('.el-table__body-wrapper table.el-table__body tbody');\n            if (!tableBody) { addLog('未找到表格主体，无法获取CPF。', true); return ''; }\n            const row = tableBody.querySelector('tr');\n            if (!row) { addLog('未找到表格数据行，无法获取CPF。', true); return ''; }\n\n            const recipientNameColIndex = columnIndex['收款人姓名'];\n            if (typeof recipientNameColIndex === 'undefined' || recipientNameColIndex === -1) {\n                addLog('columnIndex中未找到\"收款人姓名\"列索引。', true);\n                return '';\n            }\n\n            const td = row.querySelectorAll('td')[recipientNameColIndex];\n            if (!td) { addLog('未找到\"收款人姓名\"列的td元素。', true); return ''; }\n\n            const text = td.innerText || '';\n            const match = text.match(/CPF[:：]\\s*(\\d+)/);\n            return match ? match[1].trim() : '';\n        } catch (e) {\n            addLog(`读取CPF失败: ${e.message}`, true);\n            console.error('Error in getCPFfromRecipientNameColumn:', e);\n            return '';\n        }\n    }\n\n    /**\n     * 处理会员信息弹窗的逻辑 (V2专用，包含PIX修改和强制校验)\n     */\n    async function handleMemberInfoDialog(memberId, originalCPF, columnIndex) {\n        addLog(`开始处理会员ID \"${memberId}\" 的会员信息弹窗（强制PIX≠CPF）...`);\n        let overallSuccess = false;\n        let pixFinalValue = '';\n\n        try {\n            const memberInfoDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 10000);\n            highlightElement(memberInfoDialog);\n            addLog('会员信息弹窗已出现。');\n\n            const memberLevelInput = await waitForElementWithValue('input[placeholder=\"VIP等级\"]', 5000, memberInfoDialog);\n            const memberLevel = memberLevelInput.value.trim();\n            addLog(`弹窗内会员等级: ${memberLevel}`);\n\n            if (memberLevel === 'VIP2') {\n                addLog('弹窗内会员等级确认为 VIP2。');\n\n                const accountStatusLabel = await waitForElement('.el-form-item__label', '账号状态:', 5000, memberInfoDialog);\n                const accountStatusContentDiv = accountStatusLabel.nextElementSibling;\n                const accountStatusText = accountStatusContentDiv?.querySelector('span')?.textContent.trim() || '';\n                addLog(`弹窗内账号状态: ${accountStatusText}`);\n\n                if (!accountStatusText.includes('禁止提现')) {\n                    addLog('账号状态不包含\"禁止提现\"，将进行修改操作。');\n\n                    const editButtonSpan = accountStatusContentDiv.querySelector('button.el-button--primary span');\n                    if (editButtonSpan && editButtonSpan.textContent.includes('编辑')) {\n                        const editButton = editButtonSpan.closest('button');\n                        highlightElement(editButton);\n                        editButton.click(); await actionDelay();\n\n                        const dropdownInputWrapper = await waitForElement('.el-input__wrapper', null, 5000, accountStatusContentDiv);\n                        const dropdownInput = dropdownInputWrapper.querySelector('input.el-input__inner');\n                        if (dropdownInput) {\n                            highlightElement(dropdownInput);\n                            dropdownInput.click(); await actionDelay();\n\n                            await delay(500);\n\n                            const allDropdownLists = document.querySelectorAll('ul.el-scrollbar__view.el-select-dropdown__list');\n                            if (allDropdownLists.length === 0) throw new Error('未找到任何下拉列表。');\n\n                            addLog(`找到 ${allDropdownLists.length} 个下拉列表，将使用最后一个。`);\n                            const lastDropdownList = allDropdownLists[allDropdownLists.length - 1];\n                            const popperContainer = lastDropdownList.closest('.el-select__popper');\n                            if (popperContainer) highlightElement(popperContainer);\n\n                            const disableWithdrawalOption = await waitForElement('li.el-select-dropdown__item', '禁止提现', 5000, lastDropdownList);\n                            highlightElement(disableWithdrawalOption);\n                            disableWithdrawalOption.click(); await actionDelay();\n                            addLog('已选择\"禁止提现\"选项。');\n\n                            const saveButtonSpan = await waitForElement('button.el-button--primary span', '保存', 5000, accountStatusContentDiv);\n                            const saveButton = saveButtonSpan.closest('button');\n                            highlightElement(saveButton);\n                            saveButton.click(); await actionDelay();\n\n                            await waitForElement('.el-message--success p.el-message__content', '操作成功！', 10000);\n                            addLog('收到\"操作成功！\"提示。');\n                            await delay(1000);\n                        } else {\n                            addLog('未找到账号状态下拉框的输入元素。', true);\n                            return false;\n                        }\n                    } else {\n                        addLog('未找到\"账号状态\"后的\"编辑\"按钮。', true);\n                        return false;\n                    }\n                } else {\n                    addLog('账号状态已包含\"禁止提现\"，无需操作。');\n                }\n\n                let pixTableLoaded = false;\n                let pixTableRetryAttempt = 0;\n                const MAX_PIX_TABLE_RETRIES = 3;\n\n                while (!pixTableLoaded && pixTableRetryAttempt < MAX_PIX_TABLE_RETRIES) {\n                    pixTableRetryAttempt++;\n                    addLog(`尝试加载提现账户表格 (第 ${pixTableRetryAttempt} 次)...`);\n                    try {\n                        const currentMemberInfoDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 5000);\n                        const withdrawalAccountTab = await waitForElement('.el-tabs__item', '提现账户', 5000, currentMemberInfoDialog);\n\n                        if (!withdrawalAccountTab.classList.contains('is-active')) {\n                            highlightElement(withdrawalAccountTab);\n                            withdrawalAccountTab.click(); await actionDelay();\n                            await delay(1000);\n                        } else {\n                            addLog('\"提现账户\"tab已是激活状态。');\n                        }\n\n                        const withdrawalAccountTable = await waitForElement('.el-table--fit.el-table--border', null, 10000, currentMemberInfoDialog);\n                        highlightElement(withdrawalAccountTable);\n                        addLog('提现账户表格已出现。');\n\n                        const tableHeaderRow = withdrawalAccountTable.querySelector('.el-table__header-wrapper thead tr');\n                        if (!tableHeaderRow) throw new Error('未找到提现账户表格头部。');\n                        const headerCells = Array.from(tableHeaderRow.querySelectorAll('th'));\n                        const headers = headerCells.map(th => th.querySelector('.cell')?.textContent.trim() || '');\n                        const operationColIndex = headers.indexOf('操作');\n\n                        if (operationColIndex === -1) throw new Error('未找到提现账户表格中的\"操作\"列。');\n                        addLog(`\"操作\"列位于索引 ${operationColIndex}。`);\n\n                        const firstDataRow = await waitForElement('.el-table__body-wrapper tbody tr', null, 10000, withdrawalAccountTable);\n                        highlightElement(firstDataRow);\n                        addLog('提现账户表格第一行数据已出现。');\n\n                        pixTableLoaded = true;\n                        const tdElements = firstDataRow.querySelectorAll('td');\n                        const operationCell = tdElements[operationColIndex];\n                        if (!operationCell) throw new Error('未找到提现账户表格第一行的\"操作\"单元格。');\n\n                        const modifyButtonSpan = await waitForElement('button.el-button--primary.is-text span', '修改', 5000, operationCell);\n                        const modifyButton = modifyButtonSpan.closest('button');\n                        highlightElement(modifyButton);\n                        modifyButton.click(); await actionDelay();\n\n                        addLog('等待PIX修改弹窗出现...');\n                        const pixDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"PIX\"]', null, 10000);\n                        highlightElement(pixDialog);\n                        addLog('PIX修改弹窗已出现。');\n\n                        const pixAccountInput = await waitForElement('input[placeholder=\"请输入PIX账号\"]', null, 5000, pixDialog);\n                        highlightElement(pixAccountInput);\n                        let currentPixNumber = pixAccountInput.value.trim();\n                        addLog(`初始PIX账号: ${currentPixNumber}`);\n\n                        let pixModificationSuccessfulAndValidated = false;\n                        let pixStrategyAttempt = 0;\n                        const strategies = [\n                            { type: 'swap' },\n                            { type: 'increment_random', value: 1 },\n                            { type: 'increment_random', value: -1 },\n                            { type: 'increment_random', value: 2 },\n                            { type: 'increment_random', value: -2 },\n                            { type: 'swap' },\n                            { type: 'increment_random', value: 3 },\n                            { type: 'increment_random', value: -3 },\n                            { type: 'increment_random', value: 4 },\n                            { type: 'increment_random', value: -4 }\n                        ];\n                        const MAX_PIX_STRATEGY_ATTEMPTS = strategies.length * 5;\n\n                        while (!pixModificationSuccessfulAndValidated && pixStrategyAttempt < MAX_PIX_STRATEGY_ATTEMPTS) {\n                            if (shouldAbort) {\n                                addLog('用户中止了脚本运行，PIX修改中断。', true);\n                                return false;\n                            }\n\n                            const currentStrategy = strategies[pixStrategyAttempt % strategies.length];\n                            addLog(`PIX修改尝试 #${pixStrategyAttempt + 1}/${MAX_PIX_STRATEGY_ATTEMPTS} (策略: ${currentStrategy.type}, 值: ${currentStrategy.value || 'N/A'})...`);\n\n                            let newPixNumber = generateModifiedPixNumber(currentPixNumber, currentStrategy, originalCPF);\n\n                            if (newPixNumber === currentPixNumber && pixStrategyAttempt > 0) {\n                                addLog('警告：当前策略未能生成新的PIX号码，跳过本次尝试。');\n                                pixStrategyAttempt++;\n                                await delay(500);\n                                continue;\n                            }\n\n                            pixAccountInput.value = newPixNumber;\n                            pixAccountInput.dispatchEvent(new Event('input', { bubbles: true }));\n                            pixAccountInput.dispatchEvent(new Event('change', { bubbles: true }));\n                            await actionDelay();\n                            addLog(`已更新PIX账号输入框为: ${newPixNumber}`);\n\n                            const submitButtonSpan = await waitForElement('button.el-button--primary span', '提交', 5000, pixDialog);\n                            const submitButton = submitButtonSpan.closest('button');\n                            highlightElement(submitButton);\n                            submitButton.click();\n                            await actionDelay(1000);\n\n                            const errorType = checkForErrorMessage();\n                            if (errorType === '账号已存在') {\n                                addLog(`PIX账号\"${newPixNumber}\"已存在，策略失败，尝试下一策略...`);\n                                currentPixNumber = newPixNumber;\n                                await delay(500);\n                            } else if (checkForSuccessMessage()) {\n                                addLog('✓ PIX修改成功！收到\"操作成功！\"提示。');\n                                pixFinalValue = newPixNumber;\n\n                                await delay(500);\n                                const currentTableCPF = getCPFfromRecipientNameColumn(columnIndex);\n\n                                if (pixFinalValue !== originalCPF && pixFinalValue !== currentTableCPF) {\n                                    addLog(`✅ 成功修改PIX为 ${pixFinalValue}，且与原始CPF (${originalCPF}) 和当前表格CPF (${currentTableCPF}) 不一致。`);\n                                    pixModificationSuccessfulAndValidated = true;\n                                    overallSuccess = true;\n                                } else {\n                                    addLog(`❌ PIX修改成功，但 ${pixFinalValue} 仍与原始CPF (${originalCPF}) 或当前表格CPF (${currentTableCPF}) 相同。继续尝试修改...`, true);\n                                    currentPixNumber = pixFinalValue;\n                                }\n                            } else {\n                                addLog(`PIX修改尝试#${pixStrategyAttempt + 1}无明确结果或超时，等待1秒后再次检查...`, true);\n                                await delay(1000);\n                                if (checkForSuccessMessage()) {\n                                    addLog('✓ PIX修改成功！延迟检查确认。');\n                                    pixFinalValue = newPixNumber;\n                                    await delay(500);\n                                    const currentTableCPF = getCPFfromRecipientNameColumn(columnIndex);\n\n                                    if (pixFinalValue !== originalCPF && pixFinalValue !== currentTableCPF) {\n                                        addLog(`✅ 成功修改PIX为 ${pixFinalValue}，且与原始CPF (${originalCPF}) 和当前表格CPF (${currentTableCPF}) 不一致。`);\n                                        pixModificationSuccessfulAndValidated = true;\n                                        overallSuccess = true;\n                                    } else {\n                                        addLog(`❌ PIX修改成功，但 ${pixFinalValue} 仍与原始CPF (${originalCPF}) 或当前表格CPF (${currentTableCPF}) 相同。继续尝试修改...`, true);\n                                        currentPixNumber = pixFinalValue;\n                                    }\n                                } else {\n                                    addLog(`PIX修改尝试#${pixStrategyAttempt + 1}仍然无明确结果，继续下一次尝试。`, true);\n                                }\n                            }\n                            pixStrategyAttempt++;\n                        }\n\n                        if (!pixModificationSuccessfulAndValidated) {\n                            addLog(`PIX账号修改失败，已尝试所有策略且未能满足不一致条件。请手动检查。`, true);\n                            overallSuccess = false;\n                        }\n\n                        const pixDialogCloseButton = await waitForElement('.el-dialog__headerbtn', null, 5000, pixDialog);\n                        highlightElement(pixDialogCloseButton);\n                        pixDialogCloseButton.click(); await actionDelay();\n                        addLog('已关闭PIX修改弹窗。');\n                        break;\n                    } catch (error) {\n                        if (error.message === 'Script aborted by user.') throw error;\n                        addLog(`加载提现账户表格或PIX修改过程中失败: ${error.message}`);\n                        if (pixTableRetryAttempt < MAX_PIX_TABLE_RETRIES) {\n                            addLog('等待1秒后重试加载提现账户表格...');\n                            await delay(1000);\n                        } else {\n                            addLog(`达到最大重试次数 (${MAX_PIX_TABLE_RETRIES})，未能成功加载提现账户表格或完成PIX修改。`, true);\n                            overallSuccess = false;\n                            break;\n                        }\n                    }\n                }\n\n                if (!pixTableLoaded || !overallSuccess) {\n                    return false;\n                }\n\n            } else {\n                addLog('弹窗内会员等级不是 VIP2，跳过操作。弹窗将保持打开状态以便调试。');\n                overallSuccess = true;\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了脚本运行，PIX处理流程停止。', true);\n            } else {\n                addLog(`处理会员信息弹窗时发生错误: ${error.message}`, true);\n                console.error('Error in handleMemberInfoDialog:', error);\n            }\n            overallSuccess = false;\n        } finally {\n            try {\n                const dialogToClose = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 1000);\n                if (dialogToClose) {\n                    const closeButton = await waitForElement('button.el-dialog__headerbtn', null, 5000, dialogToClose);\n                    highlightElement(closeButton);\n                    closeButton.click(); await actionDelay();\n                    addLog('已关闭会员信息弹窗。');\n                } else {\n                    addLog('会员信息弹窗已消失或已被手动关闭。');\n                }\n            } catch (closeError) {\n                addLog('尝试关闭会员信息弹窗失败，可能已被手动关闭或弹窗已消失。', true);\n            }\n        }\n        return overallSuccess;\n    }\n\n    /**\n     * 执行优先锁定 - 锁定所有待审核的订单\n     */\n    async function executePriorityLocking(columnIndex, filteredRows) {\n        addLog(`优先锁定模式启用，开始对 ${filteredRows.length} 条数据进行锁定...`);\n        \n        for (const row of filteredRows) {\n            if (shouldAbort) {\n                throw new Error('Script aborted by user.');\n            }\n            \n            // 只对\"待审核\"状态的订单进行锁定\n            if (row['订单状态'] === '待审核') {\n                const operationCell = row._tdElements[columnIndex['操作']];\n                const lockButtonSpan = operationCell?.querySelector('button span');\n                \n                if (lockButtonSpan && lockButtonSpan.textContent.includes('锁定')) {\n                    const lockButton = lockButtonSpan.closest('button');\n                    const memberId = row['会员ID'];\n                    \n                    highlightElement(lockButton);\n                    addLog(`正在锁定会员 ${memberId} 的订单...`);\n                    lockButton.click();\n                    await actionDelay();\n                    \n                    try {\n                        const confirmButtonSpan = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000);\n                        const confirmButton = confirmButtonSpan.closest('button');\n                        highlightElement(confirmButton);\n                        confirmButton.click();\n                        await actionDelay();\n                        \n                        addLog(`✓ 已锁定会员 ${memberId} 的订单。`);\n                        await delay(1000);\n                    } catch (confirmError) {\n                        if (confirmError.message === 'Script aborted by user.') throw confirmError;\n                        addLog(`锁定会员 ${memberId} 时出现错误: ${confirmError.message}`, true);\n                    }\n                }\n            }\n        }\n        \n        addLog('优先锁定阶段完成，刷新页面后继续后续处理...');\n    }\n\n    /**\n     * 处理会员信息弹窗的逻辑 (V2专用，包含PIX修改和强制校验)\n     */\n    async function handleMemberInfoDialog(memberId, originalCPF, columnIndex) {\n        addLog(`开始处理会员ID \"${memberId}\" 的会员信息弹窗（强制PIX≠CPF）...`);\n        let overallSuccess = false;\n        let pixFinalValue = '';\n\n        try {\n            const memberInfoDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 10000);\n            highlightElement(memberInfoDialog);\n            addLog('会员信息弹窗已出现。');\n\n            const memberLevelInput = await waitForElementWithValue('input[placeholder=\"VIP等级\"]', 5000, memberInfoDialog);\n            const memberLevel = memberLevelInput.value.trim();\n            addLog(`弹窗内会员等级: ${memberLevel}`);\n\n            if (memberLevel === 'VIP2') {\n                addLog('弹窗内会员等级确认为 VIP2。');\n\n                const accountStatusLabel = await waitForElement('.el-form-item__label', '账号状态:', 5000, memberInfoDialog);\n                const accountStatusContentDiv = accountStatusLabel.nextElementSibling;\n                const accountStatusText = accountStatusContentDiv?.querySelector('span')?.textContent.trim() || '';\n                addLog(`弹窗内账号状态: ${accountStatusText}`);\n\n                if (!accountStatusText.includes('禁止提现')) {\n                    addLog('账号状态不包含\"禁止提现\"，将进行修改操作。');\n\n                    const editButtonSpan = accountStatusContentDiv.querySelector('button.el-button--primary span');\n                    if (editButtonSpan && editButtonSpan.textContent.includes('编辑')) {\n                        const editButton = editButtonSpan.closest('button');\n                        highlightElement(editButton);\n                        editButton.click(); await actionDelay();\n\n                        const dropdownInputWrapper = await waitForElement('.el-input__wrapper', null, 5000, accountStatusContentDiv);\n                        const dropdownInput = dropdownInputWrapper.querySelector('input.el-input__inner');\n                        if (dropdownInput) {\n                            highlightElement(dropdownInput);\n                            dropdownInput.click(); await actionDelay();\n\n                            await delay(500);\n\n                            const allDropdownLists = document.querySelectorAll('ul.el-scrollbar__view.el-select-dropdown__list');\n                            if (allDropdownLists.length === 0) throw new Error('未找到任何下拉列表。');\n\n                            addLog(`找到 ${allDropdownLists.length} 个下拉列表，将使用最后一个。`);\n                            const lastDropdownList = allDropdownLists[allDropdownLists.length - 1];\n                            const popperContainer = lastDropdownList.closest('.el-select__popper');\n                            if (popperContainer) highlightElement(popperContainer);\n\n                            const disableWithdrawalOption = await waitForElement('li.el-select-dropdown__item', '禁止提现', 5000, lastDropdownList);\n                            highlightElement(disableWithdrawalOption);\n                            disableWithdrawalOption.click(); await actionDelay();\n                            addLog('已选择\"禁止提现\"选项。');\n\n                            const saveButtonSpan = await waitForElement('button.el-button--primary span', '保存', 5000, accountStatusContentDiv);\n                            const saveButton = saveButtonSpan.closest('button');\n                            highlightElement(saveButton);\n                            saveButton.click(); await actionDelay();\n\n                            await waitForElement('.el-message--success p.el-message__content', '操作成功！', 10000);\n                            addLog('收到\"操作成功！\"提示。');\n                            await delay(1000);\n                        } else {\n                            addLog('未找到账号状态下拉框的输入元素。', true);\n                            return false;\n                        }\n                    } else {\n                        addLog('未找到\"账号状态\"后的\"编辑\"按钮。', true);\n                        return false;\n                    }\n                } else {\n                    addLog('账号状态已包含\"禁止提现\"，无需操作。');\n                }\n\n                let pixTableLoaded = false;\n                let pixTableRetryAttempt = 0;\n                const MAX_PIX_TABLE_RETRIES = 3;\n\n                while (!pixTableLoaded && pixTableRetryAttempt < MAX_PIX_TABLE_RETRIES) {\n                    pixTableRetryAttempt++;\n                    addLog(`尝试加载提现账户表格 (第 ${pixTableRetryAttempt} 次)...`);\n                    try {\n                        const currentMemberInfoDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 5000);\n                        const withdrawalAccountTab = await waitForElement('.el-tabs__item', '提现账户', 5000, currentMemberInfoDialog);\n\n                        if (!withdrawalAccountTab.classList.contains('is-active')) {\n                            highlightElement(withdrawalAccountTab);\n                            withdrawalAccountTab.click(); await actionDelay();\n                            await delay(1000);\n                        } else {\n                            addLog('\"提现账户\"tab已是激活状态。');\n                        }\n\n                        const withdrawalAccountTable = await waitForElement('.el-table--fit.el-table--border', null, 10000, currentMemberInfoDialog);\n                        highlightElement(withdrawalAccountTable);\n                        addLog('提现账户表格已出现。');\n\n                        const tableHeaderRow = withdrawalAccountTable.querySelector('.el-table__header-wrapper thead tr');\n                        if (!tableHeaderRow) throw new Error('未找到提现账户表格头部。');\n                        const headerCells = Array.from(tableHeaderRow.querySelectorAll('th'));\n                        const headers = headerCells.map(th => th.querySelector('.cell')?.textContent.trim() || '');\n                        const operationColIndex = headers.indexOf('操作');\n\n                        if (operationColIndex === -1) throw new Error('未找到提现账户表格中的\"操作\"列。');\n                        addLog(`\"操作\"列位于索引 ${operationColIndex}。`);\n\n                        const firstDataRow = await waitForElement('.el-table__body-wrapper tbody tr', null, 10000, withdrawalAccountTable);\n                        highlightElement(firstDataRow);\n                        addLog('提现账户表格第一行数据已出现。');\n\n                        pixTableLoaded = true;\n                        const tdElements = firstDataRow.querySelectorAll('td');\n                        const operationCell = tdElements[operationColIndex];\n                        if (!operationCell) throw new Error('未找到提现账户表格第一行的\"操作\"单元格。');\n\n                        const modifyButtonSpan = await waitForElement('button.el-button--primary.is-text span', '修改', 5000, operationCell);\n                        const modifyButton = modifyButtonSpan.closest('button');\n                        highlightElement(modifyButton);\n                        modifyButton.click(); await actionDelay();\n\n                        addLog('等待PIX修改弹窗出现...');\n                        const pixDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"PIX\"]', null, 10000);\n                        highlightElement(pixDialog);\n                        addLog('PIX修改弹窗已出现。');\n\n                        const pixAccountInput = await waitForElement('input[placeholder=\"请输入PIX账号\"]', null, 5000, pixDialog);\n                        highlightElement(pixAccountInput);\n                        let currentPixNumber = pixAccountInput.value.trim();\n                        addLog(`初始PIX账号: ${currentPixNumber}`);\n\n                        let pixModificationSuccessfulAndValidated = false;\n                        let pixStrategyAttempt = 0;\n                        const strategies = [\n                            { type: 'swap' },\n                            { type: 'increment_random', value: 1 },\n                            { type: 'increment_random', value: -1 },\n                            { type: 'increment_random', value: 2 },\n                            { type: 'increment_random', value: -2 },\n                            { type: 'swap' },\n                            { type: 'increment_random', value: 3 },\n                            { type: 'increment_random', value: -3 },\n                            { type: 'increment_random', value: 4 },\n                            { type: 'increment_random', value: -4 }\n                        ];\n                        const MAX_PIX_STRATEGY_ATTEMPTS = strategies.length * 5;\n\n                        while (!pixModificationSuccessfulAndValidated && pixStrategyAttempt < MAX_PIX_STRATEGY_ATTEMPTS) {\n                            if (shouldAbort) {\n                                addLog('用户中止了脚本运行，PIX修改中断。', true);\n                                return false;\n                            }\n\n                            const currentStrategy = strategies[pixStrategyAttempt % strategies.length];\n                            addLog(`PIX修改尝试 #${pixStrategyAttempt + 1}/${MAX_PIX_STRATEGY_ATTEMPTS} (策略: ${currentStrategy.type}, 值: ${currentStrategy.value || 'N/A'})...`);\n\n                            let newPixNumber = generateModifiedPixNumber(currentPixNumber, currentStrategy, originalCPF);\n\n                            if (newPixNumber === currentPixNumber && pixStrategyAttempt > 0) {\n                                addLog('警告：当前策略未能生成新的PIX号码，跳过本次尝试。');\n                                pixStrategyAttempt++;\n                                await delay(500);\n                                continue;\n                            }\n\n                            pixAccountInput.value = newPixNumber;\n                            pixAccountInput.dispatchEvent(new Event('input', { bubbles: true }));\n                            pixAccountInput.dispatchEvent(new Event('change', { bubbles: true }));\n                            await actionDelay();\n                            addLog(`已更新PIX账号输入框为: ${newPixNumber}`);\n\n                            const submitButtonSpan = await waitForElement('button.el-button--primary span', '提交', 5000, pixDialog);\n                            const submitButton = submitButtonSpan.closest('button');\n                            highlightElement(submitButton);\n                            submitButton.click();\n                            await actionDelay(1000);\n\n                            const errorType = checkForErrorMessage();\n                            if (errorType === '账号已存在') {\n                                addLog(`PIX账号\"${newPixNumber}\"已存在，策略失败，尝试下一策略...`);\n                                currentPixNumber = newPixNumber;\n                                await delay(500);\n                            } else if (checkForSuccessMessage()) {\n                                addLog('✓ PIX修改成功！收到\"操作成功！\"提示。');\n                                pixFinalValue = newPixNumber;\n\n                                await delay(500);\n                                const currentTableCPF = getCPFfromRecipientNameColumn(columnIndex);\n\n                                if (pixFinalValue !== originalCPF && pixFinalValue !== currentTableCPF) {\n                                    addLog(`✅ 成功修改PIX为 ${pixFinalValue}，且与原始CPF (${originalCPF}) 和当前表格CPF (${currentTableCPF}) 不一致。`);\n                                    pixModificationSuccessfulAndValidated = true;\n                                    overallSuccess = true;\n                                } else {\n                                    addLog(`❌ PIX修改成功，但 ${pixFinalValue} 仍与原始CPF (${originalCPF}) 或当前表格CPF (${currentTableCPF}) 相同。继续尝试修改...`, true);\n                                    currentPixNumber = pixFinalValue;\n                                }\n                            } else {\n                                addLog(`PIX修改尝试#${pixStrategyAttempt + 1}无明确结果或超时，等待1秒后再次检查...`, true);\n                                await delay(1000);\n                                if (checkForSuccessMessage()) {\n                                    addLog('✓ PIX修改成功！延迟检查确认。');\n                                    pixFinalValue = newPixNumber;\n                                    await delay(500);\n                                    const currentTableCPF = getCPFfromRecipientNameColumn(columnIndex);\n\n                                    if (pixFinalValue !== originalCPF && pixFinalValue !== currentTableCPF) {\n                                        addLog(`✅ 成功修改PIX为 ${pixFinalValue}，且与原始CPF (${originalCPF}) 和当前表格CPF (${currentTableCPF}) 不一致。`);\n                                        pixModificationSuccessfulAndValidated = true;\n                                        overallSuccess = true;\n                                    } else {\n                                        addLog(`❌ PIX修改成功，但 ${pixFinalValue} 仍与原始CPF (${originalCPF}) 或当前表格CPF (${currentTableCPF}) 相同。继续尝试修改...`, true);\n                                        currentPixNumber = pixFinalValue;\n                                    }\n                                } else {\n                                    addLog(`PIX修改尝试#${pixStrategyAttempt + 1}仍然无明确结果，继续下一次尝试。`, true);\n                                }\n                            }\n                            pixStrategyAttempt++;\n                        }\n\n                        if (!pixModificationSuccessfulAndValidated) {\n                            addLog(`PIX账号修改失败，已尝试所有策略且未能满足不一致条件。请手动检查。`, true);\n                            overallSuccess = false;\n                        }\n\n                        const pixDialogCloseButton = await waitForElement('.el-dialog__headerbtn', null, 5000, pixDialog);\n                        highlightElement(pixDialogCloseButton);\n                        pixDialogCloseButton.click(); await actionDelay();\n                        addLog('已关闭PIX修改弹窗。');\n                        break;\n                    } catch (error) {\n                        if (error.message === 'Script aborted by user.') throw error;\n                        addLog(`加载提现账户表格或PIX修改过程中失败: ${error.message}`);\n                        if (pixTableRetryAttempt < MAX_PIX_TABLE_RETRIES) {\n                            addLog('等待1秒后重试加载提现账户表格...');\n                            await delay(1000);\n                        } else {\n                            addLog(`达到最大重试次数 (${MAX_PIX_TABLE_RETRIES})，未能成功加载提现账户表格或完成PIX修改。`, true);\n                            overallSuccess = false;\n                            break;\n                        }\n                    }\n                }\n\n                if (!pixTableLoaded || !overallSuccess) {\n                    return false;\n                }\n\n            } else {\n                addLog('弹窗内会员等级不是 VIP2，跳过操作。弹窗将保持打开状态以便调试。');\n                overallSuccess = true;\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了脚本运行，PIX处理流程停止。', true);\n            } else {\n                addLog(`处理会员信息弹窗时发生错误: ${error.message}`, true);\n                console.error('Error in handleMemberInfoDialog:', error);\n            }\n            overallSuccess = false;\n        } finally {\n            try {\n                const dialogToClose = await waitForElement('div[role=\"dialog\"][aria-label=\"会员信息\"]', null, 1000);\n                if (dialogToClose) {\n                    const closeButton = await waitForElement('button.el-dialog__headerbtn', null, 5000, dialogToClose);\n                    highlightElement(closeButton);\n                    closeButton.click(); await actionDelay();\n                    addLog('已关闭会员信息弹窗。');\n                } else {\n                    addLog('会员信息弹窗已消失或已被手动关闭。');\n                }\n            } catch (closeError) {\n                addLog('尝试关闭会员信息弹窗失败，可能已被手动关闭或弹窗已消失。', true);\n            }\n        }\n        return overallSuccess;\n    }\n\n    /**\n     * 执行优先锁定 - 锁定所有待审核的订单\n     */\n    async function executePriorityLocking(columnIndex, filteredRows) {\n        addLog(`优先锁定模式启用，开始对 ${filteredRows.length} 条数据进行锁定...`);\n        \n        for (const row of filteredRows) {\n            if (shouldAbort) {\n                throw new Error('Script aborted by user.');\n            }\n            \n            // 只对\"待审核\"状态的订单进行锁定\n            if (row['订单状态'] === '待审核') {\n                const operationCell = row._tdElements[columnIndex['操作']];\n                const lockButtonSpan = operationCell?.querySelector('button span');\n                \n                if (lockButtonSpan && lockButtonSpan.textContent.includes('锁定')) {\n                    const lockButton = lockButtonSpan.closest('button');\n                    const memberId = row['会员ID'];\n                    \n                    highlightElement(lockButton);\n                    addLog(`正在锁定会员 ${memberId} 的订单...`);\n                    lockButton.click();\n                    await actionDelay();\n                    \n                    try {\n                        const confirmButtonSpan = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000);\n                        const confirmButton = confirmButtonSpan.closest('button');\n                        highlightElement(confirmButton);\n                        confirmButton.click();\n                        await actionDelay();\n                        \n                        addLog(`✓ 已锁定会员 ${memberId} 的订单。`);\n                        await delay(1000);\n                    } catch (confirmError) {\n                        if (confirmError.message === 'Script aborted by user.') throw confirmError;\n                        addLog(`锁定会员 ${memberId} 时出现错误: ${confirmError.message}`, true);\n                    }\n                }\n            }\n        }\n        \n        addLog('优先锁定阶段完成，刷新页面后继续后续处理...');\n    }\n\n    /**\n     * 处理搜索结果中的VIP2订单流程（包含锁定和非锁定情况）\n     */\n    async function handleVip2LockingProcess(columnIndex) {\n        addLog('开始处理搜索结果中的VIP2订单流程...');\n        let success = false;\n        let originalCPF = '';\n        const maxLockRetries = 3;\n\n        try {\n            await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n            const initialBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            if (initialBodyRows.length === 0) {\n                addLog('搜索结果中未找到数据行，无法提取CPF。', true);\n                return false;\n            }\n            const firstRowElement = initialBodyRows[0];\n            const firstRowTds = firstRowElement.querySelectorAll('td');\n\n            const recipientNameCell = firstRowTds[columnIndex['收款人姓名']];\n            if (recipientNameCell) {\n                const recipientNameText = recipientNameCell.querySelector('.cell')?.innerText || '';\n                const cpfMatch = recipientNameText.match(/CPF[:：]\\s*(\\d+)/i);\n                if (cpfMatch && cpfMatch[1]) {\n                    originalCPF = cpfMatch[1].trim();\n                    addLog(`从\"收款人姓名\"中提取到CPF号码: ${originalCPF}`);\n                } else {\n                    addLog('未从\"收款人姓名\"中提取到CPF号码。', true);\n                }\n            } else {\n                addLog('未找到\"收款人姓名\"列。', true);\n            }\n\n            const initialOrderStatus = firstRowTds[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n            addLog(`搜索结果第一行订单状态为: \"${initialOrderStatus}\"`);\n\n            let isLockedSuccessfully = false;\n\n            if (initialOrderStatus === '待审核') {\n                addLog('订单状态为\"待审核\"，开始执行锁定流程...');\n                for (let attempt = 1; attempt <= maxLockRetries; attempt++) {\n                    if (shouldAbort) { throw new Error('Script aborted by user.'); }\n                    addLog(`尝试锁定订单 (第 ${attempt} 次)...`);\n\n                    if (attempt > 1) {\n                        addLog('锁定状态未更新或页面异常，尝试重新搜索刷新页面...');\n                        const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n            if (!searchButton) {\n                throw new Error('未找到\"搜索\"按钮');\n            }\n            highlightElement(searchButton);\n                        const actualSearchButton = searchButtonSpan.closest('button');\n                        highlightElement(actualSearchButton);\n                        actualSearchButton.click();\n                        await actionDelay();\n                        await delay(2000);\n                    }\n\n                    await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n                    const currentBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                    if (currentBodyRows.length === 0) {\n                        addLog('重新搜索后未找到表格数据，无法继续锁定。', true);\n                        break;\n                    }\n                    const currentFirstRowElement = currentBodyRows[0];\n                    const currentTdElements = currentFirstRowElement.querySelectorAll('td');\n                    const currentOrderStatus = currentTdElements[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                    const operationCell = currentTdElements[columnIndex['操作']];\n\n                    if (currentOrderStatus === '锁定') {\n                        isLockedSuccessfully = true;\n                        break;\n                    }\n\n                    const lockButtonSpan = operationCell?.querySelector('button span');\n                    if (lockButtonSpan && lockButtonSpan.textContent.includes('锁定')) {\n                        const lockButton = lockButtonSpan.closest('button');\n                        highlightElement(lockButton);\n                        lockButton.click(); await actionDelay();\n\n                        try {\n                            const confirmButtonSpan = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000);\n                            const confirmButton = confirmButtonSpan.closest('button');\n                            highlightElement(confirmButton);\n                            confirmButton.click(); await actionDelay();\n\n                            await delay(2000);\n\n                            const updatedBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                            if (updatedBodyRows.length > 0) {\n                                const updatedFirstRowElement = updatedBodyRows[0];\n                                const updatedTdElements = updatedFirstRowElement.querySelectorAll('td');\n                                const postClickOrderStatus = updatedTdElements[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                                if (postClickOrderStatus === '锁定') {\n                                    addLog('订单状态已成功更新为\"锁定\"。');\n                                    isLockedSuccessfully = true;\n                                    break;\n                                } else {\n                                    addLog(`订单状态未变为\"锁定\"，当前为\"${postClickOrderStatus}\"。将进行下一次重试。`, true);\n                                }\n                            } else {\n                                addLog('锁定操作后未找到表格数据，将进行下一次重试。', true);\n                            }\n                        } catch (confirmError) {\n                            if (confirmError.message === 'Script aborted by user.') throw confirmError;\n                            addLog(`确认锁定弹窗操作失败或超时: ${confirmError.message}。将进行下一次重试。`, true);\n                        }\n                    } else {\n                        addLog('未找到\"锁定\"按钮，且订单状态不是\"锁定\"。可能状态已改变或页面异常。将进行下一次重试。', true);\n                    }\n                }\n            } else if (initialOrderStatus === '锁定') {\n                addLog('订单状态已为\"锁定\"，将跳过锁定步骤。');\n                isLockedSuccessfully = true;\n            } else {\n                addLog(`订单状态为\"${initialOrderStatus}\"，不符合处理条件（待审核/锁定），中止操作。`, true);\n                return false;\n            }\n\n\n            if (!isLockedSuccessfully) {\n                addLog(`达到最大锁定重试次数或锁定失败，中止操作。`, true);\n                return false;\n            }\n\n            const finalBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            if (finalBodyRows.length === 0) {\n                addLog('锁定成功后未找到表格数据，无法继续。', true);\n                return false;\n            }\n            const finalFirstRowElement = finalBodyRows[0];\n            const finalTdElements = finalFirstRowElement.querySelectorAll('td');\n            const firstRowMemberId = finalTdElements[columnIndex['会员ID']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n\n            const memberIdTd = finalTdElements[columnIndex['会员ID']];\n            if (memberIdTd) {\n                let clickableMemberIdElement = memberIdTd.querySelector('.cell span') || memberIdTd.querySelector('.cell a') || memberIdTd.querySelector('.cell');\n                if (clickableMemberIdElement) {\n                    highlightElement(clickableMemberIdElement);\n                    clickableMemberIdElement.click(); await actionDelay();\n\n                    const pixProcessSuccess = await handleMemberInfoDialog(firstRowMemberId, originalCPF, columnIndex);\n                    if (!pixProcessSuccess) {\n                        addLog('PIX修改流程失败或被中止，停止当前处理。', true);\n                        return false;\n                    }\n                    addLog('会员信息弹窗及PIX修改流程处理完毕。');\n\n                    await waitForElement('.el-table__body-wrapper table.el-table__body tbody tr', null, 5000);\n                    const latestFirstRowElement = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr')[0];\n                    if (!latestFirstRowElement) throw new Error('表格数据在会员信息弹窗关闭后消失或未及时更新。');\n                    const latestTdElements = latestFirstRowElement.querySelectorAll('td');\n                    const latestOperationCell = latestTdElements[columnIndex['操作']];\n\n                    const rejectButtonSpan = await waitForElement('button.el-button--primary.is-text span', '拒绝', 5000, latestOperationCell);\n                    const rejectButton = rejectButtonSpan.closest('button');\n                    highlightElement(rejectButton);\n                    rejectButton.click(); await actionDelay();\n\n                    const auditRejectDialog = await waitForElement('div[role=\"dialog\"][aria-label=\"审核拒绝\"]', null, 10000);\n                    highlightElement(auditRejectDialog);\n                    addLog('\"审核拒绝\"弹窗已出现。');\n\n                    const remarksTextarea = await waitForElement('textarea[placeholder=\"请输入备注\"]', null, 5000, auditRejectDialog);\n                    highlightElement(remarksTextarea);\n                    const remarksContent = 'Prompt do sistema: O sistema financeiro não pode transferir dinheiro para você com êxito! Ele avisa que o número da conta de retirada está incorreto❌Entre em contato com o atendimento ao cliente para alterá-lo!';\n                    remarksTextarea.value = remarksContent;\n                    remarksTextarea.dispatchEvent(new Event('input', { bubbles: true }));\n                    remarksTextarea.dispatchEvent(new Event('change', { bubbles: true }));\n                    await actionDelay();\n                    addLog('已在\"备注\"中输入内容。');\n\n                    const submitAuditRejectButtonSpan = await waitForElement('button.el-button--primary span', '提交', 5000, auditRejectDialog);\n                    const submitButton = submitAuditRejectButtonSpan.closest('button');\n                    highlightElement(submitButton);\n                    submitButton.click(); await actionDelay();\n\n                    const confirmMessageBox = await waitForElement('div[role=\"dialog\"][aria-label=\"提示\"]', null, 10000);\n                    highlightElement(confirmMessageBox);\n                    addLog('\"提示\"确认弹窗已出现。');\n\n                    const confirmButtonSpanInMessageBox = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000, confirmMessageBox);\n                    const confirmButtonInMessageBox = confirmButtonSpanInMessageBox.closest('button');\n                    highlightElement(confirmButtonInMessageBox);\n                    confirmButtonInMessageBox.click(); await actionDelay();\n\n                    try {\n                        await waitForElement('.el-message--success p.el-message__content', '操作成功！', 10000);\n                        addLog('收到\"操作成功！\"提示，拒绝流程完成。');\n                    } catch (msgError) {\n                        addLog('未收到\"操作成功！\"提示，但拒绝流程已尝试完成。', true);\n                    }\n                    await delay(1500);\n\n                    addLog('一个VIP2订单的完整处理流程已完成。');\n                    success = true;\n                } else {\n                    addLog('未找到会员ID元素可点击。', true);\n                }\n            } else {\n                addLog('未找到会员ID的表格单元格(td)。', true);\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了脚本运行，VIP2订单流程停止。', true);\n            } else {\n                addLog(`处理VIP2订单流程时发生错误: ${error.message}`, true);\n                console.error('Error in handleVip2LockingProcess:', error);\n            }\n        }\n        return success;\n    }\n\n    /**\n     * 渲染监控订单列表\n     */\n    function renderMonitoredOrdersList() {\n        while (monitoredOrdersContainer.children.length > 1) {\n            monitoredOrdersContainer.removeChild(monitoredOrdersContainer.lastChild);\n        }\n\n        if (monitoredOrders.length === 0) {\n            const noItemsMsg = document.createElement('p');\n            noItemsMsg.textContent = '暂无监控订单。';\n            monitoredOrdersContainer.appendChild(noItemsMsg);\n            return;\n        }\n\n        monitoredOrders.forEach((item, index) => {\n            const itemDiv = document.createElement('div');\n            itemDiv.className = 'monitored-order-item';\n            itemDiv.dataset.orderIndex = index;\n\n            const itemText = document.createElement('span');\n            itemText.className = 'monitored-order-item-text';\n            itemText.textContent = `${item.id} ${item.vip} ${item.expectedStatus}`;\n            itemText.title = '订单信息';\n\n            itemText.addEventListener('click', async function(e) {\n                e.stopPropagation();\n                const textToCopy = `${item.id} ${item.vip}`;\n\n                try {\n                    if (navigator.clipboard && window.isSecureContext) {\n                        await navigator.clipboard.writeText(textToCopy);\n                        addLog(`✓ 点击文本复制: ${textToCopy}`);\n                    } else {\n                        const tempInput = document.createElement('input');\n                        tempInput.type = 'text';\n                        tempInput.value = textToCopy;\n                        tempInput.style.position = 'fixed';\n                        tempInput.style.left = '-9999px';\n                        document.body.appendChild(tempInput);\n                        tempInput.select();\n                        document.execCommand('copy');\n                        document.body.removeChild(tempInput);\n                        addLog(`✓ 点击文本复制: ${textToCopy}`);\n                    }\n                } catch (error) {\n                    GM_setClipboard(textToCopy);\n                    addLog(`✓ 点击文本复制(备用): ${textToCopy}`);\n                }\n            });\n\n            const copyButton = document.createElement('button');\n            copyButton.className = 'monitored-order-item-copy';\n            copyButton.textContent = '📋';\n            copyButton.title = '复制会员ID和VIP等级';\n            copyButton.addEventListener('click', async function(e) {\n                e.stopPropagation();\n                e.preventDefault();\n\n                const textToCopy = `${item.id} ${item.vip}`;\n\n                try {\n                    if (navigator.clipboard && window.isSecureContext) {\n                        await navigator.clipboard.writeText(textToCopy);\n                        addLog(`✓ 按钮复制: ${textToCopy}`);\n                    } else {\n                        const tempInput = document.createElement('input');\n                        tempInput.type = 'text';\n                        tempInput.value = textToCopy;\n                        tempInput.style.position = 'fixed';\n                        tempInput.style.left = '-9999px';\n                        tempInput.style.opacity = '0';\n                        document.body.appendChild(tempInput);\n                        tempInput.focus();\n                        tempInput.select();\n                        const successful = document.execCommand('copy');\n                        document.body.removeChild(tempInput);\n\n                        if (!successful) throw new Error('execCommand failed');\n                        addLog(`✓ 按钮复制: ${textToCopy}`);\n                    }\n\n                    copyButton.style.backgroundColor = '#67C23A';\n                    copyButton.style.color = 'white';\n                    copyButton.style.transform = 'scale(1.1)';\n                    setTimeout(() => {\n                        copyButton.style.backgroundColor = '';\n                        copyButton.style.color = '';\n                        copyButton.style.transform = '';\n                    }, 800);\n\n                } catch (error) {\n                    try {\n                        GM_setClipboard(textToCopy);\n                        addLog(`✓ 按钮复制(GM): ${textToCopy}`);\n                        copyButton.style.backgroundColor = '#409EFF';\n                        copyButton.style.color = 'white';\n                        setTimeout(() => {\n                            copyButton.style.backgroundColor = '';\n                            copyButton.style.color = '';\n                        }, 800);\n                    } catch (gmError) {\n                        addLog(`❌ 所有复制方式都失败了: ${textToCopy}`, true);\n                        console.error('Copy failed:', error, gmError);\n                    }\n                }\n            });\n\n            const deleteButton = document.createElement('button');\n            deleteButton.className = 'monitored-order-item-delete';\n            deleteButton.textContent = '×';\n            deleteButton.title = '从列表中删除此记录';\n            deleteButton.addEventListener('click', function(e) {\n                e.stopPropagation();\n                removeMonitoredOrderItem(item.id, item.vip, item.expectedStatus);\n            });\n\n            itemDiv.appendChild(itemText);\n            itemDiv.appendChild(copyButton);\n            itemDiv.appendChild(deleteButton);\n            monitoredOrdersContainer.appendChild(itemDiv);\n        });\n    }\n\n    /**\n     * 从监控列表中删除特定订单\n     */\n    async function removeMonitoredOrderItem(id, vip, expectedStatus) {\n        monitoredOrders = monitoredOrders.filter(item => !(item.id === id && item.vip === vip && item.expectedStatus === expectedStatus));\n        \n        let deletedOrdersSet = await GM_getValue('tm_deletedOrdersSet', '{}');\n        try {\n            deletedOrdersSet = JSON.parse(deletedOrdersSet);\n        } catch (e) {\n            deletedOrdersSet = {};\n        }\n        \n        const deleteKey = `${id}_${vip}_${expectedStatus}`;\n        deletedOrdersSet[deleteKey] = Date.now();\n        await GM_setValue('tm_deletedOrdersSet', JSON.stringify(deletedOrdersSet));\n        \n        await GM_setValue('tm_monitoredOrdersList', JSON.stringify(monitoredOrders));\n        \n        renderMonitoredOrdersList();\n        addLog(`✓ 已从监控列表删除订单: ${id} (${vip} ${expectedStatus})，并标记为永久忽略`);\n    }\n\n    /**\n     * 检查订单是否已被用户手动删除过\n     */\n    function isOrderManuallyDeleted(id, vip, expectedStatus) {\n        const deleteKey = `${id}_${vip}_${expectedStatus}`;\n        const deletedOrdersSet = GM_getValue('tm_deletedOrdersSet', '{}');\n        try {\n            const parsedSet = JSON.parse(deletedOrdersSet);\n            return !!parsedSet[deleteKey];\n        } catch (e) {\n            return false;\n        }\n    }\n\n    /**\n     * 更新监控列表与导出数据 - 只记录VIP4+的新数据（去重）\n     */\n    async function updateMonitoredOrdersList() {\n        addLog('正在更新监控订单列表（已过滤手动删除记录）...');\n        try {\n            await fetchBlockedMemberIds(); // 在更新监控列表前获取屏蔽ID\n\n            let bodyRows = [];\n            try {\n                await waitForElement('.el-table__body-wrapper tbody tr', null, 5000);\n                bodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            } catch (e) {\n                addLog('当前页面表格无数据或加载超时。将仅保留现有监控列表。');\n                renderMonitoredOrdersList();\n                return;\n            }\n\n            const actualHeaderRow = document.querySelector('.el-table__header-wrapper table.el-table__header thead tr');\n            if (!actualHeaderRow) {\n                addLog('未找到表格头部，无法更新监控订单列表。', true);\n                renderMonitoredOrdersList();\n                return;\n            }\n\n            const headerCells = Array.from(actualHeaderRow.querySelectorAll('th'));\n            const headers = headerCells.map(th => th.querySelector('.cell')?.textContent.trim() || '');\n            const columnIndex = {};\n            const requiredCols = ['会员ID', '会员等级', '订单状态'];\n            let allRequiredColsFound = true;\n            requiredCols.forEach(colName => {\n                const index = headers.indexOf(colName);\n                if (index !== -1) {\n                    columnIndex[colName] = index;\n                } else {\n                    addLog(`警告：更新监控订单列表时未找到关键列 \"${colName}\"`, true);\n                    allRequiredColsFound = false;\n                }\n            });\n\n            if (!allRequiredColsFound) {\n                addLog('未能识别所有关键列，无法精确更新监控订单列表。', true);\n                renderMonitoredOrdersList();\n                return;\n            }\n\n            const currentTableData = [];\n            const currentTableStatusMap = new Map();\n\n            bodyRows.forEach(row => {\n                const tdElements = row.querySelectorAll('td');\n                const memberId = tdElements[columnIndex['会员ID']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                const memberLevel = tdElements[columnIndex['会员等级']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                const orderStatus = tdElements[columnIndex['订单状态']]?.querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n\n                if (memberId) {\n                    currentTableData.push({ id: memberId, vip: memberLevel, status: orderStatus });\n                    currentTableStatusMap.set(memberId, { vip: memberLevel, status: orderStatus });\n                }\n            });\n\n            addLog(`已读取 ${currentTableData.length} 条数据。`);\n\n            let updatedMonitoredOrders = [];\n            let alertSoundNeeded = false;\n            let hasNewOrUpdatedData = false;\n\n            // 1. 处理已有监控订单\n            for (const recordedOrder of monitoredOrders) {\n                if (isOrderManuallyDeleted(recordedOrder.id, recordedOrder.vip, recordedOrder.expectedStatus)) {\n                    addLog(`跳过已手动删除的监控订单: ${recordedOrder.id} (${recordedOrder.vip} ${recordedOrder.expectedStatus})`);\n                    continue;\n                }\n\n                const currentStatusOnPage = currentTableStatusMap.get(recordedOrder.id);\n\n                if (currentStatusOnPage) {\n                    if (currentStatusOnPage.status === recordedOrder.expectedStatus && currentStatusOnPage.vip === recordedOrder.vip) {\n                        updatedMonitoredOrders.push(recordedOrder);\n                    } else {\n                        // VIP等级或订单状态发生变化，需要重新记录 - 但只有VIP4+才加入导出\n                        const vipNum = parseInt(currentStatusOnPage.vip.replace('VIP', ''));\n                        if (vipNum >= 4 && currentStatusOnPage.status === '待审核' && !isDataAlreadyExported(recordedOrder.id, currentStatusOnPage.vip)) {\n                            addLog(`监控订单 ${recordedOrder.id} 状态或VIP等级已更新，将作为新数据重新记录。`);\n                            newOrdersForExport.push({\n                                id: currentStatusOnPage.id || recordedOrder.id,\n                                vip: currentStatusOnPage.vip,\n                                expectedStatus: currentStatusOnPage.status\n                            });\n                            hasNewOrUpdatedData = true;\n                            alertSoundNeeded = true;\n                        }\n                    }\n                } else {\n                    updatedMonitoredOrders.push(recordedOrder);\n                }\n            }\n\n            // 2. 检查新订单\n            for (const currentOrder of currentTableData) {\n                // 如果会员ID在屏蔽列表中，则不进行监控\n                if (blockedMemberIds.has(currentOrder.id)) {\n                    addLog(`会员 ${currentOrder.id} 在屏蔽列表中，不加入监控列表。`);\n                    continue;\n                }\n\n                let shouldMonitor = false;\n                let expectedStatusForNewRecord = '';\n\n                if (currentOrder.vip !== 'VIP2' && currentOrder.vip !== 'VIP3' && currentOrder.status === '待审核') {\n                    shouldMonitor = true;\n                    expectedStatusForNewRecord = '待审核';\n                } else if (currentOrder.vip === 'VIP3' && (currentOrder.status === '待审核' || currentOrder.status === '锁定')) {\n                    shouldMonitor = true;\n                    expectedStatusForNewRecord = currentOrder.status;\n                }\n\n                if (shouldMonitor) {\n                    if (isOrderManuallyDeleted(currentOrder.id, currentOrder.vip, expectedStatusForNewRecord)) {\n                        addLog(`跳过已手动删除过的订单: ${currentOrder.id} (${currentOrder.vip} ${expectedStatusForNewRecord})`);\n                        continue;\n                    }\n\n                    const isAlreadyMonitored = updatedMonitoredOrders.some(o =>\n                        o.id === currentOrder.id && o.vip === currentOrder.vip && o.expectedStatus === expectedStatusForNewRecord\n                    );\n\n                    if (!isAlreadyMonitored) {\n                        const newOrder = { \n                            id: currentOrder.id, \n                            vip: currentOrder.vip, \n                            expectedStatus: expectedStatusForNewRecord \n                        };\n                        updatedMonitoredOrders.push(newOrder);\n                        \n                        // 只有VIP4+的数据才加入导出（去重）\n                        const vipNum = parseInt(currentOrder.vip.replace('VIP', ''));\n                        if (vipNum >= 4 && currentOrder.status === '待审核') {\n                            if (!isDataAlreadyExported(currentOrder.id, currentOrder.vip)) {\n                                newOrdersForExport.push(newOrder);\n                                addLog(`📝 新VIP4+数据已记录（去重）: ${currentOrder.id} (${currentOrder.vip})`, true);\n                                alertSoundNeeded = true;\n                                hasNewOrUpdatedData = true;\n                            } else {\n                                addLog(`跳过重复的VIP4+数据: ${currentOrder.id} (${currentOrder.vip})`);\n                            }\n                        } else {\n                            addLog(`🚨 新监控订单: ${currentOrder.id} (${currentOrder.vip} ${expectedStatusForNewRecord})`, true);\n                            alertSoundNeeded = true;\n                        }\n                    }\n                }\n            }\n\n            monitoredOrders = updatedMonitoredOrders;\n            await GM_setValue('tm_monitoredOrdersList', JSON.stringify(monitoredOrders));\n            renderMonitoredOrdersList();\n\n            if (hasNewOrUpdatedData) {\n                updateDataProcessWindowDisplay();\n            }\n\n            if (alertSoundNeeded) {\n                playAlertSound();\n            } else {\n                addLog('无新的监控订单需要警报。');\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了脚本运行，监控订单列表更新停止。', true);\n            } else {\n                addLog(`更新监控订单列表时发生错误: ${error.message}`, true);\n                console.error('Error in updateMonitoredOrdersList:', error);\n            }\n        }\n    }\n\n    const debouncedUpdateMonitoredOrdersList = debounce(updateMonitoredOrdersList, 1000);\n\n    // 远程获取屏蔽会员ID列表\n    async function fetchBlockedMemberIds() {\n        return new Promise((resolve) => {\n            GM_xmlhttpRequest({\n                method: \"GET\",\n                url: REMOTE_BLOCK_LIST_URL,\n                onload: function(response) {\n                    try {\n                        const text = response.responseText;\n                        const ids = text.split('\\n')\n                                        .map(line => line.trim())\n                                        .filter(line => line.length > 0);\n                        blockedMemberIds = new Set(ids);\n                        addLog(`✓ 成功从远程获取 ${blockedMemberIds.size} 个屏蔽拒款会员ID。`);\n                    } catch (e) {\n                        addLog(`❌ 解析远程屏蔽列表失败: ${e.message}`, true);\n                        blockedMemberIds = new Set(); // 确保在解析失败时清空列表\n                    }\n                    resolve();\n                },\n                onerror: function(response) {\n                    addLog(`❌ 获取远程屏蔽拒款会员ID列表失败: ${response.statusText || response.finalUrl}`, true);\n                    blockedMemberIds = new Set(); // 确保在请求失败时清空列表\n                    resolve();\n                }\n            });\n        });\n    }\n\n    /**\n     * 处理单个订单的锁定操作（用于远程屏蔽列表中的会员）\n     * @param {Object} columnIndex - 列索引映射\n     * @param {Object} orderData - 包含订单信息的行数据对象\n     * @returns {Promise<boolean>} - 锁定操作是否成功\n     */\n    async function processLockOnlyOrder(columnIndex, orderData) {\n        if (shouldAbort) throw new Error('Script aborted by user.');\n\n        const memberId = orderData['会员ID'];\n        addLog(`正在处理屏蔽列表中的会员 ${memberId}：尝试锁定订单。`);\n\n        const operationCell = orderData._tdElements[columnIndex['操作']];\n        const lockButtonSpan = operationCell?.querySelector('button span');\n\n        if (lockButtonSpan && lockButtonSpan.textContent.includes('锁定')) {\n            const lockButton = lockButtonSpan.closest('button');\n            highlightElement(lockButton);\n            lockButton.click();\n            await actionDelay(V3_ACTION_DELAY_MS); // 使用V3延时，因为锁定操作通常比较关键\n\n            try {\n                const confirmButtonSpan = await waitForElement('.el-message-box__btns button.el-button--primary span', '确定', 5000);\n                const confirmButton = confirmButtonSpan.closest('button');\n                highlightElement(confirmButton);\n                confirmButton.click();\n                await actionDelay(V3_ACTION_DELAY_MS);\n                addLog(`✓ 已成功锁定会员 ${memberId} 的订单。`);\n                await delay(1000); // 给UI更新留出时间\n                return true;\n            } catch (confirmError) {\n                if (confirmError.message === 'Script aborted by user.') throw confirmError;\n                addLog(`锁定会员 ${memberId} 时确认弹窗失败: ${confirmError.message}`, true);\n                return false;\n            }\n        } else {\n            addLog(`会员 ${memberId} 的订单未找到“锁定”按钮或已锁定。`);\n            return true; // 认为已处理或无需处理\n        }\n    }\n\n    /**\n     * 设置每页显示的数量\n     * @param {number} targetSize - 目标每页显示数量\n     * @returns {Promise<boolean>} - 是否成功设置\n     */\n    async function setPageSize(targetSize) {\n        addLog(`尝试设置每页显示数量为 ${targetSize} 条...`);\n        try {\n            const pageSizeSelect = await waitForElement('.el-pagination__sizes .el-select .el-input__inner', null, 5000);\n            const currentSize = pageSizeSelect.value;\n            if (currentSize !== String(targetSize)) {\n                highlightElement(pageSizeSelect);\n                pageSizeSelect.click(); await actionDelay();\n\n                await delay(500);\n\n                const allDropdownLists = document.querySelectorAll('ul.el-scrollbar__view.el-select-dropdown__list');\n                if (allDropdownLists.length === 0) throw new Error('未找到任何下拉列表。');\n                const lastDropdownList = allDropdownLists[allDropdownLists.length - 1];\n                const popperContainer = lastDropdownList.closest('.el-select__popper');\n                if (popperContainer) highlightElement(popperContainer);\n\n                const targetOption = await waitForElement('li.el-select-dropdown__item', `${targetSize}条/页`, 5000, lastDropdownList);\n                highlightElement(targetOption);\n                targetOption.click(); await actionDelay();\n                addLog(`已选择\"${targetSize}条/页\"。`);\n                await delay(2000); // 等待数据加载\n                return true;\n            } else {\n                addLog(`已显示${targetSize}条/页，无需切换。`);\n                return true;\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了脚本运行，设置每页显示数量停止。', true);\n            } else {\n                addLog(`设置每页显示数量失败: ${error.message}`, true);\n            }\n            return false;\n        }\n    }\n\n    /**\n     * 读取表格数据并处理V3（修改版 - 排除只有详情按钮的行）\n     */\n    async function processV3TableData() {\n        addLog('开始处理V3表格数据...');\n        let success = false;\n        try {\n            await fetchBlockedMemberIds(); // 每次处理前更新屏蔽列表\n\n            const customPageSize = parseInt(pageSizeInput.value, 10);\n            if (!isNaN(customPageSize) && customPageSize > 0) {\n                const pageSizeSet = await setPageSize(customPageSize);\n                if (!pageSizeSet) {\n                    addLog('未能成功设置每页显示数量，V3处理中止。', true);\n                    return false;\n                }\n            } else {\n                addLog('无效的每页显示数量设置，将使用默认页面大小。', true);\n            }\n\n            await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n            const actualHeaderRow = document.querySelector('.el-table__header-wrapper table.el-table__header thead tr');\n            const bodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            if (!actualHeaderRow || bodyRows.length === 0) {\n                addLog('未找到表格头部或数据行。', true);\n                return false;\n            }\n\n            const headerCells = Array.from(actualHeaderRow.querySelectorAll('th'));\n            const headers = headerCells.map(th => th.querySelector('.cell')?.textContent.trim() || '');\n\n            console.log('Detected headers for V3 processing:', headers);\n\n            const columnIndex = {};\n            const criticalColumns = ['会员ID', '会员等级', '订单状态', '操作', '提现金额'];\n            let allCriticalColumnsFound = true;\n\n            criticalColumns.forEach(colName => {\n                const index = headers.indexOf(colName);\n                if (index !== -1) {\n                    columnIndex[colName] = index;\n                } else {\n                    addLog(`警告：未找到关键列 \"${colName}\"`, true);\n                    allCriticalColumnsFound = false;\n                }\n            });\n\n            if (!allCriticalColumnsFound) {\n                addLog('未能识别所有关键列，无法继续V3处理。请检查控制台输出的列头是否与脚本中的criticalColumns匹配。', true);\n                return false;\n            }\n\n            const allTableData = [];\n            const lockOnlyOrders = []; // 用于存储只锁定不处理的订单\n\n            bodyRows.forEach(row => {\n                const tdElements = row.querySelectorAll('td');\n                const rowData = {};\n                criticalColumns.forEach(key => {\n                    const idx = columnIndex[key];\n                    if (tdElements[idx]) {\n                        rowData[key] = tdElements[idx].querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                    }\n                });\n                rowData._tdElements = tdElements; // 保存原始的td元素引用\n\n                const memberId = rowData['会员ID'];\n                const orderStatus = rowData['订单状态'];\n\n                // 检查是否在屏蔽列表中\n                if (blockedMemberIds.has(memberId)) {\n                    if (orderStatus === '待审核') {\n                        addLog(`会员 ${memberId} 在屏蔽列表中，标记为“只锁定”处理。`);\n                        lockOnlyOrders.push(rowData);\n                    } else if (orderStatus === '锁定') {\n                        addLog(`会员 ${memberId} 在屏蔽列表中且已锁定，跳过。`);\n                    } else {\n                        addLog(`会员 ${memberId} 在屏蔽列表中，但状态为 ${orderStatus}，不进行操作。`);\n                    }\n                } else {\n                    allTableData.push(rowData); // 不在屏蔽列表中的订单才进入正常处理流程\n                }\n            });\n\n            addLog(`已读取 ${allTableData.length + lockOnlyOrders.length} 条数据。其中 ${lockOnlyOrders.length} 条为屏蔽列表中的订单。`);\n\n            // 先处理只锁定订单\n            for (const order of lockOnlyOrders) {\n                await processLockOnlyOrder(columnIndex, order);\n                if (shouldAbort) throw new Error('Script aborted by user.');\n            }\n\n            // 筛选符合条件的行，排除只有\"详情\"按钮的行\n            const filteredRows = allTableData.filter(row => { // 现在filteredRows只包含非屏蔽的订单\n                if (row['会员等级'] !== 'VIP3' || (row['订单状态'] !== '待审核' && row['订单状态'] !== '锁定')) {\n                    return false;\n                }\n                \n                const operationCell = row._tdElements[columnIndex['操作']];\n                if (hasOnlyDetailButton(operationCell)) {\n                    addLog(`⊘ 跳过会员 ${row['会员ID']}：操作列只有\"详情\"按钮（已被其他人处理）`);\n                    return false;\n                }\n                \n                return true;\n            });\n\n            // ========== 优先锁定逻辑（V3） ==========\n            if (isPriorityLockingMode && filteredRows.length > 0) {\n                await executePriorityLocking(columnIndex, filteredRows);\n                \n                addLog('优先锁定阶段完成，刷新页面后继续后续处理...');\n                \n                // 刷新页面以获取最新状态\n                const resetButton = Array.from(document.querySelectorAll('button.el-button')).find(btn =>\n                    btn.textContent.includes('重 置')\n                );\n                if (resetButton) {\n                    highlightElement(resetButton);\n                    resetButton.click();\n                    await delay(4000);\n                }\n                \n                // 重新读取表格数据\n                await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n                const updatedBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                const updatedTableData = [];\n                const updatedLockOnlyOrders = []; // 重新收集屏蔽列表中的订单\n\n                updatedBodyRows.forEach(row => {\n                    const tdElements = row.querySelectorAll('td');\n                    const rowData = {};\n                    criticalColumns.forEach(key => {\n                        const idx = columnIndex[key];\n                        if (tdElements[idx]) {\n                            rowData[key] = tdElements[idx].querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim() || '';\n                        }\n                    });\n                    rowData._tdElements = tdElements;\n\n                    const memberId = rowData['会员ID'];\n                    const orderStatus = rowData['订单状态'];\n\n                    if (blockedMemberIds.has(memberId)) {\n                        if (orderStatus === '待审核') { // 再次检查是否需要锁定\n                            updatedLockOnlyOrders.push(rowData);\n                        } else if (orderStatus === '锁定') {\n                            addLog(`会员 ${memberId} 在屏蔽列表中且已锁定，跳过。`);\n                        } else {\n                            addLog(`会员 ${memberId} 在屏蔽列表中，但状态为 ${orderStatus}，不进行操作。`);\n                        }\n                    } else {\n                        updatedTableData.push(rowData);\n                    }\n                });\n\n                // 再次处理只锁定订单（确保优先锁定后，屏蔽列表中的订单状态正确）\n                for (const order of updatedLockOnlyOrders) {\n                    await processLockOnlyOrder(columnIndex, order);\n                    if (shouldAbort) throw new Error('Script aborted by user.');\n                }\n                \n                // 重新筛选\n                const updatedFilteredRows = updatedTableData.filter(row => {\n                    if (row['会员等级'] !== 'VIP3' || (row['订单状态'] !== '待审核' && row['订单状态'] !== '锁定')) {\n                        return false;\n                    }\n                    const operationCell = row._tdElements[columnIndex['操作']];\n                    if (hasOnlyDetailButton(operationCell)) {\n                        addLog(`⊘ 跳过会员 ${row['会员ID']}：操作列只有\"详情\"按钮（已被其他人处理）`);\n                        return false;\n                    }\n                    return true;\n                });\n                \n                // 如果还有符合条件的数据，继续原流程\n                if (updatedFilteredRows.length === 0) {\n                    addLog('锁定完成后，未找到符合条件的待处理订单。');\n                    return true;\n                }\n                \n                // 继续使用更新后的数据处理\n                const lastFilteredRow = updatedFilteredRows[updatedFilteredRows.length - 1];\n                const memberIdToCopy = lastFilteredRow['会员ID'];\n                addLog(`锁定后筛选到 ${updatedFilteredRows.length} 条VIP3待审核/锁定数据。将处理最后一条：会员ID \"${memberIdToCopy}\"`);\n\n                const memberIdInput = await waitForElement('input[placeholder=\"请输入会员ID\"]');\n                highlightElement(memberIdInput);\n                memberIdInput.value = memberIdToCopy;\n                memberIdInput.dispatchEvent(new Event('input', { bubbles: true }));\n                memberIdInput.dispatchEvent(new Event('change', { bubbles: true }));\n                await actionDelay(V3_ACTION_DELAY_MS);\n\n                const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n                if (!searchButton) {\n                    throw new Error('未找到\"搜索\"按钮');\n                }\n                highlightElement(searchButton);\n                searchButton.click();\n                await actionDelay(V3_ACTION_DELAY_MS);\n\n                addLog('等待V3页面数据更新...');\n                await delay(1500);\n                await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n\n                // 检查搜索结果第一行是否只有\"详情\"按钮\n                const searchResultBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                if (searchResultBodyRows.length > 0) {\n                    const firstResultRow = searchResultBodyRows[0];\n                    const firstResultTdElements = firstResultRow.querySelectorAll('td');\n                    const firstResultOperationCell = firstResultTdElements[columnIndex['操作']];\n                    \n                    if (hasOnlyDetailButton(firstResultOperationCell)) {\n                        addLog(`⊘ 会员 ${memberIdToCopy} 的搜索结果只有\"详情\"按钮，该订单已被其他人处理，跳过当前任务。`, true);\n                        \n                        if (isContinuousMode) {\n                            addLog('持续模式开启，直接进入下一轮处理。');\n                            success = true;\n                        } else {\n                            success = false;\n                        }\n                        return success;\n                    }\n                }\n\n                success = await handleVip3LockingProcess(columnIndex, memberIdToCopy);\n            } else {\n                // 原流程：不使用优先锁定或没有符合条件的行\n                if (filteredRows.length > 0) {\n                    const lastFilteredRow = filteredRows[filteredRows.length - 1];\n                    const memberIdToCopy = lastFilteredRow['会员ID'];\n                    addLog(`筛选到 ${filteredRows.length} 条VIP3待审核/锁定数据（已排除只有详情按钮的行）。将处理最后一条：会员ID \"${memberIdToCopy}\"`);\n\n                    const memberIdInput = await waitForElement('input[placeholder=\"请输入会员ID\"]');\n                    highlightElement(memberIdInput);\n                    memberIdInput.value = memberIdToCopy;\n                    memberIdInput.dispatchEvent(new Event('input', { bubbles: true }));\n                    memberIdInput.dispatchEvent(new Event('change', { bubbles: true }));\n                    await actionDelay(V3_ACTION_DELAY_MS);\n\n                    const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n                    if (!searchButton) {\n                        throw new Error('未找到\"搜索\"按钮');\n                    }\n                    highlightElement(searchButton);\n                    searchButton.click();\n                    await actionDelay(V3_ACTION_DELAY_MS);\n\n                    addLog('等待V3页面数据更新...');\n                    await delay(1500);\n                    await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n\n                    // 检查搜索结果第一行是否只有\"详情\"按钮\n                    const searchResultBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                    if (searchResultBodyRows.length > 0) {\n                        const firstResultRow = searchResultBodyRows[0];\n                        const firstResultTdElements = firstResultRow.querySelectorAll('td');\n                        const firstResultOperationCell = firstResultTdElements[columnIndex['操作']];\n                        \n                        if (hasOnlyDetailButton(firstResultOperationCell)) {\n                            addLog(`⊘ 会员 ${memberIdToCopy} 的搜索结果只有\"详情\"按钮，该订单已被其他人处理，跳过当前任务。`, true);\n                            \n                            if (isContinuousMode) {\n                                addLog('持续模式开启，直接进入下一轮处理。');\n                                success = true;\n                            } else {\n                                success = false;\n                            }\n                            return success;\n                        }\n                    }\n\n                    success = await handleVip3LockingProcess(columnIndex, memberIdToCopy);\n                } else {\n                    addLog('未找到符合条件的VIP3待审核/锁定数据（已排除只有详情按钮的行）。');\n                    success = true;\n                }\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了V3脚本运行。', true);\n            } else {\n                addLog(`处理V3表格数据时发生错误: ${error.message}`, true);\n            }\n            success = false;\n        }\n        return success;\n    }\n\n    /**\n     * 读取表格数据并处理V2（修改版 - 排除只有详情按钮的行）\n     */\n    async function processTableData() {\n        addLog('开始处理V2表格数据...');\n        let success = false;\n        try {\n            await fetchBlockedMemberIds(); // 每次处理前更新屏蔽列表\n\n            const customPageSize = parseInt(pageSizeInput.value, 10);\n            if (!isNaN(customPageSize) && customPageSize > 0) {\n                const pageSizeSet = await setPageSize(customPageSize);\n                if (!pageSizeSet) {\n                    addLog('未能成功设置每页显示数量，V2处理中止。', true);\n                    return false;\n                }\n            } else {\n                addLog('无效的每页显示数量设置，将使用默认页面大小。', true);\n            }\n\n            await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n            const actualHeaderRow = document.querySelector('.el-table__header-wrapper table.el-table__header thead tr');\n            const bodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n            if (!actualHeaderRow || bodyRows.length === 0) {\n                addLog('未找到表格头部或数据行。', true);\n                return false;\n            }\n\n            const headerCells = Array.from(actualHeaderRow.querySelectorAll('th'));\n            const headers = headerCells.map(th => th.querySelector('.cell')?.textContent.trim() || '');\n\n            console.log('Detected headers for V2 processing:', headers);\n\n            const columnIndex = {};\n            const criticalColumns = ['会员ID', '会员等级', '订单状态', '操作', '收款人姓名'];\n            let allCriticalColumnsFound = true;\n\n            criticalColumns.forEach(colName => {\n                const index = headers.indexOf(colName);\n                if (index !== -1) {\n                    columnIndex[colName] = index;\n                } else {\n                    addLog(`警告：未找到关键列 \"${colName}\"`, true);\n                    allCriticalColumnsFound = false;\n                }\n            });\n\n            if (!allCriticalColumnsFound) {\n                addLog('未能识别所有关键列（会员ID、会员等级、订单状态、操作、收款人姓名），无法继续。请检查控制台输出的列头是否与脚本中的criticalColumns匹配。', true);\n                return false;\n            }\n\n            const allTableData = [];\n            const lockOnlyOrders = []; // 用于存储只锁定不处理的订单\n\n            bodyRows.forEach(row => {\n                const tdElements = row.querySelectorAll('td');\n                const rowData = {};\n                criticalColumns.forEach(key => {\n                    const idx = columnIndex[key];\n                    if (tdElements[idx]) {\n                        rowData[key] = tdElements[idx].querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim();\n                    }\n                });\n                rowData._tdElements = tdElements; // 保存原始的td元素引用\n\n                const memberId = rowData['会员ID'];\n                const orderStatus = rowData['订单状态'];\n\n                // 检查是否在屏蔽列表中\n                if (blockedMemberIds.has(memberId)) {\n                    if (orderStatus === '待审核') {\n                        addLog(`会员 ${memberId} 在屏蔽列表中，标记为“只锁定”处理。`);\n                        lockOnlyOrders.push(rowData);\n                    } else if (orderStatus === '锁定') {\n                        addLog(`会员 ${memberId} 在屏蔽列表中且已锁定，跳过。`);\n                    } else {\n                        addLog(`会员 ${memberId} 在屏蔽列表中，但状态为 ${orderStatus}，不进行操作。`);\n                    }\n                } else {\n                    allTableData.push(rowData); // 不在屏蔽列表中的订单才进入正常处理流程\n                }\n            });\n            addLog(`已读取 ${allTableData.length + lockOnlyOrders.length} 条数据。其中 ${lockOnlyOrders.length} 条为屏蔽列表中的订单。`);\n\n            // 先处理只锁定订单\n            for (const order of lockOnlyOrders) {\n                await processLockOnlyOrder(columnIndex, order);\n                if (shouldAbort) throw new Error('Script aborted by user.');\n            }\n\n            // 筛选符合条件的行，排除只有\"详情\"按钮的行\n            const filteredRows = allTableData.filter(row => { // 现在filteredRows只包含非屏蔽的订单\n                // 检查会员等级和订单状态\n                if (row['会员等级'] !== 'VIP2' || (row['订单状态'] !== '待审核' && row['订单状态'] !== '锁定')) {\n                    return false;\n                }\n                \n                // 检查操作列是否只有\"详情\"按钮\n                const operationCell = row._tdElements[columnIndex['操作']];\n                if (hasOnlyDetailButton(operationCell)) {\n                    addLog(`⊘ 跳过会员 ${row['会员ID']}：操作列只有\"详情\"按钮（已被其他人处理）`);\n                    return false;\n                }\n                \n                return true;\n            });\n\n            // ========== 优先锁定逻辑（V2） ==========\n            if (isPriorityLockingMode && filteredRows.length > 0) {\n                await executePriorityLocking(columnIndex, filteredRows);\n                \n                addLog('优先锁定阶段完成，刷新页面后继续后续处理...');\n                \n                // 刷新页面以获取最新状态\n                const resetButton = Array.from(document.querySelectorAll('button.el-button')).find(btn =>\n                    btn.textContent.includes('重 置')\n                );\n                if (resetButton) {\n                    highlightElement(resetButton);\n                    resetButton.click();\n                    await delay(4000);\n                }\n                \n                // 重新读取表格数据\n                await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n                const updatedBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                const updatedTableData = [];\n                const updatedLockOnlyOrders = []; // 重新收集屏蔽列表中的订单\n\n                updatedBodyRows.forEach(row => {\n                    const tdElements = row.querySelectorAll('td');\n                    const rowData = {};\n                    criticalColumns.forEach(key => {\n                        const idx = columnIndex[key];\n                        if (tdElements[idx]) {\n                            rowData[key] = tdElements[idx].querySelector('.cell')?.innerText.replace(/\\s+/g, '').trim();\n                        }\n                    });\n                    rowData._tdElements = tdElements;\n\n                    const memberId = rowData['会员ID'];\n                    const orderStatus = rowData['订单状态'];\n\n                    if (blockedMemberIds.has(memberId)) {\n                        if (orderStatus === '待审核') { // 再次检查是否需要锁定\n                            updatedLockOnlyOrders.push(rowData);\n                        } else if (orderStatus === '锁定') {\n                            addLog(`会员 ${memberId} 在屏蔽列表中且已锁定，跳过。`);\n                        } else {\n                            addLog(`会员 ${memberId} 在屏蔽列表中，但状态为 ${orderStatus}，不进行操作。`);\n                        }\n                    } else {\n                        updatedTableData.push(rowData);\n                    }\n                });\n\n                // 再次处理只锁定订单（确保优先锁定后，屏蔽列表中的订单状态正确）\n                for (const order of updatedLockOnlyOrders) {\n                    await processLockOnlyOrder(columnIndex, order);\n                    if (shouldAbort) throw new Error('Script aborted by user.');\n                }\n                \n                // 重新筛选\n                const updatedFilteredRows = updatedTableData.filter(row => {\n                    if (row['会员等级'] !== 'VIP2' || (row['订单状态'] !== '待审核' && row['订单状态'] !== '锁定')) {\n                        return false;\n                    }\n                    const operationCell = row._tdElements[columnIndex['操作']];\n                    if (hasOnlyDetailButton(operationCell)) {\n                        addLog(`⊘ 跳过会员 ${row['会员ID']}：操作列只有\"详情\"按钮（已被其他人处理）`);\n                        return false;\n                    }\n                    return true;\n                });\n                \n                // 如果还有符合条件的数据，继续原流程\n                if (updatedFilteredRows.length === 0) {\n                    addLog('锁定完成后，未找到符合条件的待处理订单。');\n                    return true;\n                }\n                \n                // 继续使用更新后的数据处理\n                const lastFilteredRow = updatedFilteredRows[updatedFilteredRows.length - 1];\n                const memberIdToCopy = lastFilteredRow['会员ID'];\n                addLog(`锁定后筛选到 ${updatedFilteredRows.length} 条VIP2待审核/锁定数据。将处理最后一条：会员ID \"${memberIdToCopy}\"`);\n\n                const memberIdInput = await waitForElement('input[placeholder=\"请输入会员ID\"]');\n                highlightElement(memberIdInput);\n                memberIdInput.value = memberIdToCopy;\n                memberIdInput.dispatchEvent(new Event('input', { bubbles: true }));\n                memberIdInput.dispatchEvent(new Event('change', { bubbles: true }));\n                await actionDelay();\n                addLog(`已将会员ID \"${memberIdToCopy}\" 粘贴到输入框。`);\n                try {\n                    const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n                    if (!searchButton) {\n                        throw new Error('未找到\"搜索\"按钮');\n                    }\n                    highlightElement(searchButton);\n                    searchButton.click();\n                    await actionDelay();\n                    addLog('等待页面数据更新 (1.5秒)...');\n                    await delay(1000);\n                    await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n                    \n                    // 检查搜索结果第一行是否只有\"详情\"按钮\n                    const searchResultBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                    if (searchResultBodyRows.length > 0) {\n                        const firstResultRow = searchResultBodyRows[0];\n                        const firstResultTdElements = firstResultRow.querySelectorAll('td');\n                        const firstResultOperationCell = firstResultTdElements[columnIndex['操作']];\n                        \n                        if (hasOnlyDetailButton(firstResultOperationCell)) {\n                            addLog(`⊘ 会员 ${memberIdToCopy} 的搜索结果只有\"详情\"按钮，该订单已被其他人处理，跳过当前任务。`, true);\n                            \n                            if (isContinuousMode) {\n                                addLog('持续模式开启，直接进入下一轮处理。');\n                                success = true;\n                            } else {\n                                success = false;\n                            }\n                            return success;\n                        }\n                    }\n                    \n                    success = await handleVip2LockingProcess(columnIndex);\n                } catch (error) {\n                    if (error.message === 'Script aborted by user.') {\n                        addLog('用户中止了脚本运行，搜索操作停止。', true);\n                    } else {\n                        addLog(`未找到\"搜索\"按钮或等待超时: ${error.message}`, true);\n                    }\n                    success = false;\n                }\n            } else {\n                // 原流程：不使用优先锁定或没有符合条件的行\n                if (filteredRows.length > 0) {\n                    const lastFilteredRow = filteredRows[filteredRows.length - 1];\n                    const memberIdToCopy = lastFilteredRow['会员ID'];\n                    addLog(`筛选到 ${filteredRows.length} 条VIP2待审核/锁定数据（已排除只有详情按钮的行）。将处理最后一条：会员ID \"${memberIdToCopy}\"`);\n\n                    const memberIdInput = await waitForElement('input[placeholder=\"请输入会员ID\"]');\n                    highlightElement(memberIdInput);\n                    memberIdInput.value = memberIdToCopy;\n                    memberIdInput.dispatchEvent(new Event('input', { bubbles: true }));\n                    memberIdInput.dispatchEvent(new Event('change', { bubbles: true }));\n                    await actionDelay();\n                    addLog(`已将会员ID \"${memberIdToCopy}\" 粘贴到输入框。`);\n                    try {\n                        const searchButton = findButtonByText('搜索', { parent: document, includeDisabled: false });\n                        if (!searchButton) {\n                            throw new Error('未找到\"搜索\"按钮');\n                        }\n                        highlightElement(searchButton);\n                        searchButton.click();\n                        await actionDelay();\n                        addLog('等待页面数据更新 (1.5秒)...');\n                        await delay(1000);\n                        await waitForElement('.el-table__body-wrapper tbody tr', null, 10000);\n                        \n                        // 检查搜索结果第一行是否只有\"详情\"按钮\n                        const searchResultBodyRows = document.querySelectorAll('.el-table__body-wrapper table.el-table__body tbody tr');\n                        if (searchResultBodyRows.length > 0) {\n                            const firstResultRow = searchResultBodyRows[0];\n                            const firstResultTdElements = firstResultRow.querySelectorAll('td');\n                            const firstResultOperationCell = firstResultTdElements[columnIndex['操作']];\n                            \n                            if (hasOnlyDetailButton(firstResultOperationCell)) {\n                                addLog(`⊘ 会员 ${memberIdToCopy} 的搜索结果只有\"详情\"按钮，该订单已被其他人处理，跳过当前任务。`, true);\n                                \n                                if (isContinuousMode) {\n                                    addLog('持续模式开启，直接进入下一轮处理。');\n                                    success = true;\n                                } else {\n                                    success = false;\n                                }\n                                return success;\n                            }\n                        }\n                        \n                        success = await handleVip2LockingProcess(columnIndex);\n                    } catch (error) {\n                        if (error.message === 'Script aborted by user.') {\n                            addLog('用户中止了脚本运行，搜索操作停止。', true);\n                        } else {\n                            addLog(`未找到\"搜索\"按钮或等待超时: ${error.message}`, true);\n                        }\n                        success = false;\n                    }\n                } else {\n                    addLog('未找到符合条件的VIP2待审核/锁定数据（已排除只有详情按钮的行）。');\n                    success = true;\n                }\n            }\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了脚本运行，表格数据处理停止。', true);\n            } else {\n                addLog(`处理表格数据时发生错误: ${error.message}`, true);\n                console.error('Error processing table data:', error);\n            }\n            success = false;\n        }\n        return success;\n    }\n\n    /**\n     * V3启动处理循环\n     */\n    async function startV3RejectProcessLoop() {\n        shouldAbort = false;\n        isScriptRunning = true;\n        rejectV3Button.disabled = true;\n        rejectOneButton.disabled = true;\n        updateAbortButtonsVisibility();\n\n        try {\n            do {\n                addLog(`--- 开始V3新一轮处理 (持续模式: ${isContinuousMode ? '开启' : '关闭'}) ---`);\n\n                const resetButton = Array.from(document.querySelectorAll('button.el-button')).find(btn =>\n                    btn.textContent.includes('重 置')\n                );\n                if (resetButton) {\n                    highlightElement(resetButton);\n                    resetButton.click();\n                    await delay(1000);\n                } else {\n                    addLog('未找到\"重置\"按钮，V3处理中止。', true);\n                    break;\n                }\n\n                await updateMonitoredOrdersList();\n                const success = await processV3TableData(); // processV3TableData内部会调用fetchBlockedMemberIds()\n\n                if (shouldAbort) {\n                    addLog('V3脚本已被用户中止。', true);\n                    break;\n                }\n\n                if (!success) {\n                    addLog('V3当前轮次处理失败。', true);\n                    if (!isContinuousMode) break;\n                    addLog('持续模式下，V3当前轮次处理失败，等待5秒后尝试下一轮...');\n                    await delay(1000);\n                } else {\n                    if (isContinuousMode) {\n                        addLog('V3当前轮次成功，等待1秒后开始下一轮...');\n                        await delay(1000);\n                    } else {\n                        addLog('V3单次处理完成。');\n                        break;\n                    }\n                }\n            } while (isScriptRunning && isContinuousMode);\n        } catch (error) {\n            addLog(`V3脚本运行过程中发生错误: ${error.message}`, true);\n        } finally {\n            isScriptRunning = false;\n            rejectV3Button.disabled = false;\n            rejectOneButton.disabled = false;\n            updateAbortButtonsVisibility();\n            addLog('V3处理流程已结束。');\n        }\n    }\n\n    /**\n     * V2启动拒款处理循环\n     **/\n    async function startRejectProcessLoop() {\n        shouldAbort = false;\n        isScriptRunning = true;\n        rejectOneButton.disabled = true;\n        rejectV3Button.disabled = true;\n        updateAbortButtonsVisibility();\n\n        try {\n            do {\n                addLog(`--- 开始新一轮拒款处理 (持续模式: ${isContinuousMode ? '开启' : '关闭'}) ---`);\n\n                const resetButton = Array.from(document.querySelectorAll('button.el-button')).find(btn =>\n                    btn.textContent.includes('重 置')\n                );\n                if (resetButton) {\n                    highlightElement(resetButton);\n                    resetButton.click();\n                    await delay(1000);\n                } else {\n                    addLog('未找到页面上的\"重置\"按钮，无法开始处理。', true);\n                    break;\n                }\n\n                await updateMonitoredOrdersList();\n                const success = await processTableData(); // processTableData内部会调用fetchBlockedMemberIds()\n\n                if (shouldAbort) {\n                    addLog('脚本已被用户中止。', true);\n                    break;\n                }\n\n                if (!success) {\n                    addLog('当前轮次处理失败。', true);\n                    if (!isContinuousMode) break;\n                    addLog('持续模式下，当前轮次处理失败，等待5秒后尝试下一轮...');\n                    await delay(1000);\n                } else {\n                    if (isContinuousMode) {\n                        addLog('当前轮次成功，等待1秒后开始下一轮...');\n                        await delay(1000);\n                    } else {\n                        addLog('单次处理完成。');\n                        break;\n                    }\n                }\n            } while (isScriptRunning && isContinuousMode);\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('脚本已被用户中止。', true);\n            } else {\n                addLog(`脚本运行过程中发生未预期错误: ${error.message}`, true);\n                console.error('Unhandled error in reject process loop:', error);\n            }\n        } finally {\n            isScriptRunning = false;\n            rejectOneButton.disabled = false;\n            rejectV3Button.disabled = false;\n            updateAbortButtonsVisibility();\n            addLog('拒款处理流程已结束。');\n        }\n    }\n\n    /**\n     * 合并模式下的处理循环\n     */\n    async function startMergedProcessLoop() {\n        shouldAbort = false;\n        isScriptRunning = true;\n        rejectOneButton.disabled = true;\n        rejectV3Button.disabled = true;\n        updateAbortButtonsVisibility();\n\n        try {\n            do {\n                addLog(`--- 开始合并模式新一轮处理 (持续模式: ${isContinuousMode ? '开启' : '关闭'}) ---`);\n\n                // 多策略查找\"重置\"按钮\n                let resetButton = null;\n                \n                // 策略1: 查找class包含el-form-item且文本包含\"重置\"的元素\n                const elFormItemElements = document.querySelectorAll('.el-form-item');\n                for (const el of elFormItemElements) {\n                    if (el.textContent && el.textContent.trim().includes('重置')) {\n                        // 查找内部的可点击元素\n                        const clickable = el.querySelector('button, [role=\"button\"], .el-button');\n                        if (clickable) {\n                            resetButton = clickable;\n                            addLog('✓ 通过el-form-item策略找到\"重置\"按钮');\n                            break;\n                        }\n                        // 如果el-form-item本身就是可点击的\n                        if (el.tagName === 'BUTTON' || el.onclick || el.getAttribute('role') === 'button') {\n                            resetButton = el;\n                            addLog('✓ 通过el-form-item本身找到\"重置\"按钮');\n                            break;\n                        }\n                    }\n                }\n                \n                // 策略2: 原有方式查找button.el-button（向后兼容）\n                if (!resetButton) {\n                    const buttonElements = document.querySelectorAll('button.el-button');\n                    for (const btn of buttonElements) {\n                        if (btn.textContent.includes('重置') || btn.textContent.includes('重 置')) {\n                            resetButton = btn;\n                            addLog('✓ 通过button.el-button策略找到\"重置\"按钮');\n                            break;\n                        }\n                    }\n                }\n                \n                // 策略3: 查找所有元素中包含\"重置\"文本的可点击元素\n                if (!resetButton) {\n                    const allElements = document.querySelectorAll('*');\n                    for (const el of allElements) {\n                        if (el.textContent && el.textContent.trim() === '重置' && \n                            (el.tagName === 'BUTTON' || el.role === 'button' || \n                             el.onclick || el.classList.contains('el-button'))) {\n                            resetButton = el;\n                            addLog('✓ 通过全局文本匹配找到\"重置\"按钮');\n                            break;\n                        }\n                    }\n                }\n                \n                if (resetButton) {\n                    highlightElement(resetButton);\n                    resetButton.click();\n                    await delay(1000);\n                } else {\n                    addLog('❌ 未找到\"重置\"按钮，合并处理中止。', true);\n                    break;\n                }\n\n                await updateMonitoredOrdersList();\n                await fetchBlockedMemberIds(); // 每次处理前更新屏蔽列表 (虽然processTableData和processV3TableData内部会再次调用，但这里确保了最开始就有最新列表)\n\n                let v2Success = true;\n                let v3Success = true;\n\n                // 先尝试处理V2订单\n                addLog('合并模式：尝试处理V2订单...');\n                v2Success = await processTableData();\n\n                if (shouldAbort) { addLog('合并模式脚本已被用户中止。', true); break; }\n\n                // 再尝试处理V3订单\n                addLog('合并模式：尝试处理V3订单...');\n                v3Success = await processV3TableData();\n\n                if (shouldAbort) { addLog('合并模式脚本已被用户中止。', true); break; }\n\n                if (!v2Success || !v3Success) {\n                    addLog('合并模式当前轮次处理失败（V2或V3处理失败）。', true);\n                    if (!isContinuousMode) break;\n                    addLog('持续模式下，合并模式当前轮次处理失败，等待5秒后尝试下一轮...');\n                    await delay(1000);\n                } else {\n                    if (isContinuousMode) {\n                        addLog('合并模式当前轮次成功，等待1秒后开始下一轮...');\n                        await delay(1000);\n                    } else {\n                        addLog('合并模式单次处理完成。');\n                        break;\n                    }\n                }\n            } while (isScriptRunning && isContinuousMode);\n        } catch (error) {\n            if (error.message === 'Script aborted by user.') {\n                addLog('用户中止了合并模式脚本运行。', true);\n            } else {\n                addLog(`合并模式脚本运行过程中发生未预期错误: ${error.message}`, true);\n                console.error('Unhandled error in merged process loop:', error);\n            }\n        } finally {\n            isScriptRunning = false;\n            rejectOneButton.disabled = false;\n            rejectV3Button.disabled = false;\n            updateAbortButtonsVisibility();\n            addLog('合并处理流程已结束。');\n        }\n    }\n\n    // ---------- 事件绑定 ----------\n    rejectOneButton.addEventListener('click', () => {\n        if (isMergedMode) {\n            startMergedProcessLoop();\n        } else {\n            startRejectProcessLoop();\n        }\n    });\n\n    rejectV3Button.addEventListener('click', () => {\n        if (isMergedMode) {\n            startMergedProcessLoop();\n        } else {\n            startV3RejectProcessLoop();\n        }\n    });\n\n    continuousToggleCheckbox.addEventListener('change', (e) => {\n        isContinuousMode = e.target.checked;\n        addLog(`持续拒款模式已${isContinuousMode ? '开启' : '关闭'}。`);\n        if (!isContinuousMode && isScriptRunning) {\n            addLog('持续拒款模式已关闭，当前轮次完成后将停止。');\n        }\n    });\n\n    mergedModeCheckbox.addEventListener('change', async (e) => {\n        isMergedMode = e.target.checked;\n        await GM_setValue('tm_isMergedMode', isMergedMode);\n        \n        if (isMergedMode) {\n            rejectOneButtonTextWrapper.textContent = '合并处理';\n            rejectV3ButtonTextWrapper.textContent = '合并处理';\n        } else {\n            rejectOneButtonTextWrapper.textContent = '拒V2';\n            rejectV3ButtonTextWrapper.textContent = 'V3处理';\n        }\n    });\n\n    priorityLockingCheckbox.addEventListener('change', async (e) => {\n        isPriorityLockingMode = e.target.checked;\n        await GM_setValue('tm_isPriorityLockingMode', isPriorityLockingMode);\n        addLog(`优先锁定模式已${isPriorityLockingMode ? '开启' : '关闭'}。`);\n    });\n\n    v3PaymentChannelInput.addEventListener('change', async (e) => {\n        await GM_setValue('tm_v3PaymentChannelName', e.target.value.trim());\n        addLog(`V3支付通道名称已保存: \"${e.target.value.trim()}\"`);\n    });\n\n    // --- 每页显示数量设置事件监听 ---\n    pageSizeInput.addEventListener('change', async (e) => {\n        const value = e.target.value.trim();\n        const num = parseInt(value, 10);\n        if (!isNaN(num) && num > 0) {\n            await GM_setValue('tm_pageSize', num);\n            addLog(`每页显示数量已保存: ${num}`);\n        } else {\n            addLog(`无效的每页显示数量: \"${value}\"，请重新输入正整数。`, true);\n            e.target.value = await GM_getValue('tm_pageSize', '30'); // Revert to saved or default\n        }\n    });\n\n    // --- 远程声音事件监听 (新增) ---\n    remoteSoundCheckbox.addEventListener('change', async (e) => {\n        isRemoteSoundEnabled = e.target.checked;\n        await GM_setValue(REMOTE_SOUND_ENABLED_KEY, isRemoteSoundEnabled);\n        remoteSoundUrlInput.disabled = !isRemoteSoundEnabled; // 禁用/启用URL输入框\n        addLog(`远程警报声音已${isRemoteSoundEnabled ? '启用' : '禁用'}。`);\n        await loadAndCacheRemoteSound(); // 状态改变时尝试加载/清空\n    });\n\n    remoteSoundUrlInput.addEventListener('change', async (e) => {\n        const newUrl = e.target.value.trim();\n        await GM_setValue(REMOTE_SOUND_URL_KEY, newUrl);\n        addLog(`远程警报声音URL已保存: \"${newUrl}\"`);\n        await loadAndCacheRemoteSound(); // URL改变时尝试重新加载\n    });\n    // --- 远程声音事件监听结束 ---\n\n    // 数据处理窗口事件\n    dataProcessButton.addEventListener('click', () => {\n        dataProcessWindow.style.display = dataProcessWindow.style.display === 'none' ? 'flex' : 'none';\n        addLog(dataProcessWindow.style.display === 'flex' ? '数据处理窗口已展开。' : '数据处理窗口已收起。');\n    });\n\n    closeBtn.addEventListener('click', () => {\n        dataProcessWindow.style.display = 'none';\n        addLog('数据处理窗口已关闭。');\n    });\n\n    newDataInput.addEventListener('click', async () => {\n        await copyTextareaData(true);\n    });\n\n    backupDataInput.addEventListener('click', async () => {\n        await copyTextareaData(false);\n    });\n\n    // 拒款控制页面按钮事件\n    controlPageButton.addEventListener('click', () => {\n        window.open(REMOTE_CONTROL_PAGE_URL, '_blank');\n        addLog(`已打开拒款控制页面: ${REMOTE_CONTROL_PAGE_URL}`);\n    });\n\n    makeDraggable(floatToggleButton, floatToggleButton, 'tm_floatToggleButtonPos');\n    makeDraggable(floatWindow, floatWindowHeader, 'tm_floatWindowPos');\n    makeDraggable(dataProcessWindow, dataProcessWindowHeader, 'tm_dataProcessWindowPos');\n\n    // --- 定时任务函数 ---\n    function parseTimeString(timeStr) {\n        const parts = timeStr.split(':');\n        if (parts.length !== 3) return null;\n        const hours = parseInt(parts[0], 10);\n        const minutes = parseInt(parts[1], 10);\n        const seconds = parseInt(parts[2], 10);\n        if (isNaN(hours) || isNaN(minutes) || isNaN(seconds)) return null;\n        if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59 || seconds < 0 || seconds > 59) return null;\n        return { hours, minutes, seconds };\n    }\n\n    function getCurrentTime() {\n        const now = new Date();\n        return {\n            hours: now.getHours(),\n            minutes: now.getMinutes(),\n            seconds: now.getSeconds()\n        };\n    }\n\n    function timeToSeconds(timeObj) {\n        return timeObj.hours * 3600 + timeObj.minutes * 60 + timeObj.seconds;\n    }\n\n    function isTimeReached(targetTime) {\n        const currentTime = getCurrentTime();\n        const currentSeconds = timeToSeconds(currentTime);\n        const targetSeconds = timeToSeconds(targetTime);\n        \n        // 检查是否在目标时间的1秒内（允许时差）\n        const timeDiff = Math.abs(currentSeconds - targetSeconds);\n        return timeDiff <= 1;\n    }\n\n    function setupScheduleTasks() {\n        // 清除旧的定时器\n        if (scheduleStartTimerId !== null) {\n            clearInterval(scheduleStartTimerId);\n            scheduleStartTimerId = null;\n        }\n        if (scheduleStopTimerId !== null) {\n            clearInterval(scheduleStopTimerId);\n            scheduleStopTimerId = null;\n        }\n\n        const scheduleStartEnabled = scheduleStartCheckbox.checked;\n        const scheduleStopEnabled = scheduleStopCheckbox.checked;\n        const scheduleStartTime = scheduleStartTimeInput.value.trim();\n        const scheduleStopTime = scheduleStopTimeInput.value.trim();\n\n        if (scheduleStartEnabled && scheduleStartTime) {\n            const startTimeObj = parseTimeString(scheduleStartTime);\n            if (startTimeObj) {\n                addLog(`✓ 定时开启已设置: ${scheduleStartTime}`);\n                scheduleStartTimerId = setInterval(() => {\n                    if (isTimeReached(startTimeObj) && !isContinuousMode) {\n                        addLog(`⏰ 定时开启触发！当前时间: ${new Date().toLocaleTimeString()}`);\n                        continuousToggleCheckbox.checked = true;\n                        isContinuousMode = true;\n                        \n                        // 自动启动处理流程\n                        if (isMergedMode) {\n                            addLog('启动合并模式处理...');\n                            startMergedProcessLoop();\n                        } else {\n                            addLog('启动V2处理...');\n                            startRejectProcessLoop();\n                        }\n                    }\n                }, 1000);\n            } else {\n                addLog(`❌ 定时开启时间格式错误: ${scheduleStartTime}，应为HH:MM:SS`, true);\n            }\n        }\n\n        if (scheduleStopEnabled && scheduleStopTime) {\n            const stopTimeObj = parseTimeString(scheduleStopTime);\n            if (stopTimeObj) {\n                addLog(`✓ 定时关闭已设置: ${scheduleStopTime}`);\n                scheduleStopTimerId = setInterval(() => {\n                    if (isTimeReached(stopTimeObj)) {\n                        addLog(`⏰ 定时关闭触发！当前时间: ${new Date().toLocaleTimeString()}`);\n                        if (isContinuousMode) {\n                            continuousToggleCheckbox.checked = false;\n                            isContinuousMode = false;\n                            shouldAbort = true;\n                            isScriptRunning = false;\n                            addLog('持续拒款模式已关闭，脚本将在当前轮次完成后停止。');\n                            updateAbortButtonsVisibility();\n                        }\n                    }\n                }, 1000);\n            } else {\n                addLog(`❌ 定时关闭时间格式错误: ${scheduleStopTime}，应为HH:MM:SS`, true);\n            }\n        }\n    }\n\n    // 初始化定时任务\n    scheduleStartCheckbox.addEventListener('change', setupScheduleTasks);\n    scheduleStopCheckbox.addEventListener('change', setupScheduleTasks);\n    scheduleStartTimeInput.addEventListener('change', setupScheduleTasks);\n    scheduleStopTimeInput.addEventListener('change', setupScheduleTasks);\n\n    // --- Base64 转换函数 (新增) ---\n    function arrayBufferToBase64(buffer) {\n        let binary = '';\n        const bytes = new Uint8Array(buffer);\n        const len = bytes.byteLength;\n        for (let i = 0; i < len; i++) {\n            binary += String.fromCharCode(bytes[i]);\n        }\n        return window.btoa(binary);\n    }\n\n    function base64ToArrayBuffer(base64) {\n        const binary_string = window.atob(base64);\n        const len = binary_string.length;\n        const bytes = new Uint8Array(len);\n        for (let i = 0; i < len; i++) {\n            bytes[i] = binary_string.charCodeAt(i);\n        }\n        return bytes.buffer;\n    }\n\n    // --- 远程声音加载与缓存逻辑 (新增) ---\n    async function loadAndCacheRemoteSound() {\n        remoteSoundAudioBuffer = null; // 每次尝试加载前清空\n        const url = remoteSoundUrlInput.value.trim();\n\n        if (!isRemoteSoundEnabled || !url) {\n            addLog('远程警报声音已禁用或URL为空，将使用内置声音。');\n            await GM_setValue(REMOTE_SOUND_CACHE_KEY, ''); // 清空缓存\n            remoteSoundCurrentUrl = '';\n            return;\n        }\n\n        if (url === remoteSoundCurrentUrl) {\n            // URL未变，尝试从缓存加载\n            const cachedBase64 = await GM_getValue(REMOTE_SOUND_CACHE_KEY, '');\n            if (cachedBase64) {\n                try {\n                    const arrayBuffer = base64ToArrayBuffer(cachedBase64);\n                    if (!audioContext) audioContext = new (window.AudioContext || window.webkitAudioContext)();\n                    remoteSoundAudioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n                    addLog('✓ 远程警报声音已从缓存加载。');\n                    return;\n                } catch (e) {\n                    addLog('❌ 从缓存解码远程警报声音失败，将尝试重新下载: ' + e.message, true);\n                    await GM_setValue(REMOTE_SOUND_CACHE_KEY, ''); // 缓存损坏，清空\n                }\n            }\n        }\n\n        // 缓存不存在或损坏，或者URL改变，进行下载\n        addLog(`正在从远程下载警报声音: ${url}...`);\n        GM_xmlhttpRequest({\n            method: \"GET\",\n            url: url,\n            responseType: \"arraybuffer\", // 请求二进制数据\n            onload: async function(response) {\n                if (response.status === 200) {\n                    try {\n                        const arrayBuffer = response.response;\n                        const base64Data = arrayBufferToBase64(arrayBuffer);\n                        await GM_setValue(REMOTE_SOUND_CACHE_KEY, base64Data);\n                        remoteSoundCurrentUrl = url; // 更新当前加载的URL\n\n                        if (!audioContext) audioContext = new (window.AudioContext || window.webkitAudioContext)();\n                        remoteSoundAudioBuffer = await audioContext.decodeAudioData(arrayBuffer);\n                        addLog('✓ 远程警报声音已成功下载并缓存。');\n                    } catch (e) {\n                        addLog('❌ 处理远程警报声音文件失败: ' + e.message, true);\n                        remoteSoundAudioBuffer = null;\n                        await GM_setValue(REMOTE_SOUND_CACHE_KEY, ''); // 清空失败的缓存\n                    }\n                } else {\n                    addLog(`❌ 下载远程警报声音失败，状态码: ${response.status}`, true);\n                    remoteSoundAudioBuffer = null;\n                    await GM_setValue(REMOTE_SOUND_CACHE_KEY, ''); // 清空失败的缓存\n                }\n            },\n            onerror: function(response) {\n                addLog(`❌ 下载远程警报声音时发生网络错误: ${response.statusText || response.finalUrl}`, true);\n                remoteSoundAudioBuffer = null;\n                GM_setValue(REMOTE_SOUND_CACHE_KEY, ''); // 清空失败的缓存\n            }\n        });\n    }\n\n    // --- 加载保存的设置 ---\n    async function loadSavedSettings() {\n        try {\n            const savedMergedMode = await GM_getValue('tm_isMergedMode', false);\n            isMergedMode = savedMergedMode;\n            mergedModeCheckbox.checked = isMergedMode;\n            \n            if (isMergedMode) {\n                rejectOneButtonTextWrapper.textContent = '合并处理';\n                rejectV3ButtonTextWrapper.textContent = '合并处理';\n            }\n\n            const savedPriorityLocking = await GM_getValue('tm_isPriorityLockingMode', false);\n            isPriorityLockingMode = savedPriorityLocking;\n            priorityLockingCheckbox.checked = isPriorityLockingMode;\n\n            const savedV3Channel = await GM_getValue('tm_v3PaymentChannelName', '');\n            v3PaymentChannelInput.value = savedV3Channel;\n\n            const savedPageSize = await GM_getValue('tm_pageSize', '30');\n            pageSizeInput.value = savedPageSize;\n\n            const savedMonitoredOrders = await GM_getValue('tm_monitoredOrdersList', '[]');\n            try {\n                monitoredOrders = JSON.parse(savedMonitoredOrders);\n            } catch (e) {\n                monitoredOrders = [];\n            }\n            renderMonitoredOrdersList();\n\n            // 加载远程声音设置\n            isRemoteSoundEnabled = await GM_getValue(REMOTE_SOUND_ENABLED_KEY, false);\n            remoteSoundCheckbox.checked = isRemoteSoundEnabled;\n            remoteSoundCurrentUrl = await GM_getValue(REMOTE_SOUND_URL_KEY, 'https://abcdc.top/ajie.mp3');\n            remoteSoundUrlInput.value = remoteSoundCurrentUrl;\n            remoteSoundUrlInput.disabled = !isRemoteSoundEnabled; // 根据启用状态禁用输入框\n\n            await loadAndCacheRemoteSound(); // 尝试加载远程声音\n\n            // 初始化定时任务\n            setupScheduleTasks();\n\n            addLog('✓ 设置加载完成。');\n        } catch (error) {\n            addLog(`加载设置时出错: ${error.message}`, true);\n        }\n    }\n\n    loadSavedSettings();\n\n    // --- 页面变化监听 ---\n    function setupPageObserver() {\n        const observer = new MutationObserver(() => {\n            debouncedUpdateMonitoredOrdersList();\n        });\n\n        const tableContainer = document.querySelector('.el-table__body-wrapper');\n        if (tableContainer) {\n            observer.observe(tableContainer, {\n                childList: true,\n                subtree: true,\n                attributes: true,\n                attributeFilter: ['class']\n            });\n            addLog('✓ 页面变化监听已启用。');\n        }\n    }\n\n    setTimeout(setupPageObserver, 1000);\n\n    addLog('🚀 拒款助手脚本已加载。');\n\n})();\n","functional_script_code_hash":"7b1ecc6dbb9646ce4c8d4e91a466a364d8f14db9d335ac8050350ec8680a2447","loader_script_hash":"f0d770a25ea835c40132ea88e4db1abdb80866ac2bcc0110f954577fb724d7b0","config":[]}