运单自动抢单助手

为运单系统添加抢单倒计时和自动抢单功能

// ==UserScript==
// @name         运单自动抢单助手
// @namespace    
// @version      1.0.4
// @description  为运单系统添加抢单倒计时和自动抢单功能
// @author       wavever
// @match        https://carrier.okguanli.com/*
// @grant        none
// @run-at       document-end
// ==/UserScript==

(function () {
    'use strict';

    // 全局变量
    let countdownIntervals = new Map(); // 存储倒计时任务
    let autoGrabTasks = new Map(); // 存储自动抢单任务
    let isProcessing = false; // 防止重复处理
    let orderDataMap = new Map(); // 存储运单数据,key为运单ID,value为运单信息
    let statusIndicator = null; // 状态指示器元素

    // 设置相关变量
    const SETTINGS_KEY = 'carrierAutoSettings';
    const DESTINATION_LIST_KEY = 'carrierDestinationList';
    const NOTE_CONFIG_KEY = 'carrierNoteConfig';
    let settings = {
        enableAutoGrab: false, // 是否启用自动抢单
        showCountdown: false,  // 是否显示倒计时
        enableAutoRefresh: false, // 是否启用自动刷新
        refreshInterval: 10, // 自动刷新间隔(秒)
        skipGrabConfirm: false, // 是否跳过抢单确认弹框
        enableDestinationMatch: false, // 是否启用目的地匹配自动抢单
    };

    // 目的地匹配列表
    let destinationList = [];

    // 备注配置
    let noteConfig = {
        mode: 'whitelist', // 'whitelist' | 'blacklist'
        whitelist: [], // 白名单关键字数组
        blacklist: [] // 黑名单关键字数组
    };

    // 目的地匹配相关变量
    let matchedOrders = new Map(); // 存储匹配到的订单
    let matchInfoPanel = null; // 浮动信息面板

    // 自动刷新相关变量
    let autoRefreshTimer = null;
    let lastRefreshTime = null;
    let isRefreshPaused = false; // 是否暂停自动刷新

    // 加载设置
    function loadSettings() {
        console.log('开始加载设置...');
        const savedSettings = localStorage.getItem(SETTINGS_KEY);
        console.log('从localStorage读取的原始数据:', savedSettings);

        if (savedSettings) {
            try {
                const parsed = JSON.parse(savedSettings);
                console.log('解析后的设置数据:', parsed);

                // 逐个字段更新,确保每个字段都被正确设置
                Object.keys(parsed).forEach(key => {
                    if (parsed[key] !== undefined && parsed[key] !== null) {
                        settings[key] = parsed[key];
                        console.log(`已更新设置字段 ${key}:`, parsed[key]);
                    }
                });

                console.log('最终加载的设置:', settings);
            } catch (e) {
                console.error('加载设置失败:', e);
            }
        } else {
            console.log('没有找到已保存的设置,使用默认设置:', settings);
        }

        // 加载目的地列表
        const savedDestinations = localStorage.getItem(DESTINATION_LIST_KEY);
        console.log('从localStorage读取的目的地数据:', savedDestinations);

        if (savedDestinations) {
            try {
                destinationList = JSON.parse(savedDestinations);
                console.log('已加载目的地列表:', destinationList);
            } catch (e) {
                console.error('加载目的地列表失败:', e);
                destinationList = [];
            }
        } else {
            console.log('没有找到已保存的目的地列表,使用空列表');
        }

        // 加载备注配置
        const savedNoteConfig = localStorage.getItem(NOTE_CONFIG_KEY);
        console.log('从localStorage读取的备注配置数据:', savedNoteConfig);

        if (savedNoteConfig) {
            try {
                noteConfig = { ...noteConfig, ...JSON.parse(savedNoteConfig) };
                console.log('已加载备注配置:', noteConfig);
            } catch (e) {
                console.error('加载备注配置失败:', e);
                noteConfig = {
                    mode: 'whitelist',
                    whitelist: [],
                    blacklist: []
                };
            }
        } else {
            console.log('没有找到已保存的备注配置,使用默认配置');
        }
    }

    // 保存设置
    function saveSettings() {
        try {
            console.log('准备保存设置到localStorage:', settings);
            const settingsStr = JSON.stringify(settings);
            console.log('序列化后的设置字符串:', settingsStr);
            localStorage.setItem(SETTINGS_KEY, settingsStr);
            console.log('设置已成功保存到localStorage');

            // 验证保存是否成功
            const verification = localStorage.getItem(SETTINGS_KEY);
            console.log('验证保存结果:', verification);
            console.log('保存验证是否成功:', verification === settingsStr);
        } catch (e) {
            console.error('保存设置到localStorage失败:', e);
        }
    }

    // 保存目的地列表
    function saveDestinationList() {
        try {
            localStorage.setItem(DESTINATION_LIST_KEY, JSON.stringify(destinationList));
            console.log('目的地列表已保存到localStorage:', destinationList);
        } catch (e) {
            console.error('保存目的地列表失败:', e);
        }
    }

    // 保存备注配置
    function saveNoteConfig() {
        try {
            localStorage.setItem(NOTE_CONFIG_KEY, JSON.stringify(noteConfig));
            console.log('备注配置已保存到localStorage:', noteConfig);
        } catch (e) {
            console.error('保存备注配置失败:', e);
        }
    }

    // 时间同步相关变量
    let ntpTimeOffset = 0; // NTP时间与本地时间的差值(毫秒)
    let isNtpSynced = false; // 是否已同步NTP时间
    let ntpSyncRetries = 0; // NTP同步重试次数
    const MAX_NTP_RETRIES = 3; // 最大重试次数
    const NTP_SERVERS = [
        'worldtimeapi.org/api/timezone/Asia/Shanghai',
        'timeapi.io/api/Time/current/zone?timeZone=Asia/Shanghai',
        'time.cloudflare.com',
        'time.google.com'
    ]; // NTP服务器列表

    // 创建设置按钮
    function createSettingsButton() {
        const settingsIcon = document.querySelector("#root > div.layout___2fuYE > div.header___2Twvl > div:nth-child(2) > label");
        if (!settingsIcon) {
            console.warn('未找到设置图标');
            return;
        }

        const ourSettingsBtn = document.createElement('label');
        ourSettingsBtn.className = 'ant-dropdown-trigger auto-grab-settings';

        // 添加悬停样式
        const style = document.createElement('style');
        style.textContent = `
            .auto-grab-settings:hover {
                background: rgba(255, 255, 255, 0.2) !important;
                transform: translateY(-1px);
                box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
            }
            .auto-grab-settings:active {
                transform: translateY(0);
                box-shadow: none;
            }
        `;
        document.head.appendChild(style);
        ourSettingsBtn.style.cssText = `
            display: inline-flex;
            align-items: center;
            font-size: 16px;
            color: rgb(255, 255, 255);
            cursor: pointer;
            margin-left: 16px;
            background: rgba(255, 255, 255, 0.1);
            padding: 4px 12px;
            border-radius: 4px;
            transition: all 0.3s;
        `;
        ourSettingsBtn.innerHTML = `
            <span role="img" aria-label="thunderbolt" class="anticon anticon-thunderbolt" style="font-size: 18px; color: #ffd700;">
                <svg viewBox="64 64 896 896" focusable="false" data-icon="thunderbolt" width="1em" height="1em" fill="currentColor" aria-hidden="true">
                    <path d="M848 359.3H627.7L825.8 109c4.1-5.3.4-13-6.3-13H436c-2.8 0-5.5 1.5-6.9 4L170 547.5c-3.1 5.3.7 12 6.9 12h174.4l-89.4 357.6c-1.9 7.8 7.5 13.3 13.3 7.7L853.5 373c5.2-4.9 1.7-13.7-5.5-13.7zM378.2 732.5l60.3-241H281.1l189.6-327.4h224.6L487 427.4h211L378.2 732.5z"/>
                </svg>
            </span>
            <span style="margin-left: 6px; font-size: 14px; font-weight: 500;">运单助手</span>
        `;

        // 插入我们的设置按钮
        settingsIcon.parentNode.insertBefore(ourSettingsBtn, settingsIcon.nextSibling);

        // 点击事件处理
        ourSettingsBtn.addEventListener('click', showSettingsModal);
    }

    // 显示设置弹窗
    function showSettingsModal() {
        console.log('=== 打开设置弹框 ===');
        console.log('当前settings:', JSON.stringify(settings, null, 2));

        // 创建模态框容器
        const modalContainer = document.createElement('div');
        modalContainer.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 9999;
        `;

        // 创建模态框内容
        const modalContent = document.createElement('div');
        modalContent.style.cssText = `
            background-color: white;
            padding: 24px;
            border-radius: 8px;
            min-width: 400px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
        `;

        // 标题
        const title = document.createElement('h3');
        title.style.cssText = 'margin: 0 0 16px 0; font-size: 16px; font-weight: 500;';
        title.textContent = '运单助手设置';

        // 设置项
        const settingsContent = document.createElement('div');
        settingsContent.style.cssText = 'margin-bottom: 24px;';

        let tempSettings = { ...settings }; // 临时设置副本

        // 自动抢单开关
        const autoGrabSwitch = createSettingSwitch(
            '启用自动抢单',
            settings.enableAutoGrab,
            (checked) => {
                tempSettings.enableAutoGrab = checked;
                console.log('临时设置更新 - 启用自动抢单:', checked);
            }
        );

        // 倒计时显示开关
        const countdownSwitch = createSettingSwitch(
            '显示倒计时',
            settings.showCountdown,
            (checked) => {
                tempSettings.showCountdown = checked;
                console.log('临时设置更新 - 显示倒计时:', checked);
            }
        );

        // 跳过确认弹框开关
        const skipConfirmSwitch = createSettingSwitch(
            '点击抢单按钮后,不再展示确认弹框 ⚠️',
            settings.skipGrabConfirm,
            (checked) => {
                tempSettings.skipGrabConfirm = checked;
                console.log('临时设置更新 - 跳过确认弹框:', checked);
            }
        );

        // 目的地匹配自动抢单开关容器
        const destinationMatchContainer = document.createElement('div');
        destinationMatchContainer.style.cssText = 'margin-bottom: 16px;';

        // 目的地匹配自动抢单开关
        const destinationMatchSwitch = createSettingSwitch(
            '目的地匹配自动抢单 🎯',
            tempSettings.enableDestinationMatch,
            (checked) => {
                tempSettings.enableDestinationMatch = checked;
                console.log('临时设置更新 - 目的地匹配自动抢单:', checked);
                // 更新配置按钮的显示状态
                configDestinationBtn.style.display = checked ? 'inline-block' : 'none';
                configNoteBtn.style.display = checked ? 'inline-block' : 'none';
            }
        );

        // 配置目的地按钮
        const configDestinationBtn = document.createElement('button');
        configDestinationBtn.type = 'button';
        configDestinationBtn.className = 'ant-btn ant-btn-link';
        configDestinationBtn.style.cssText = `
            margin-left: 8px;
            padding: 0 8px;
            font-size: 12px;
            color: #1890ff;
            display: ${tempSettings.enableDestinationMatch ? 'inline-block' : 'none'};
        `;
        configDestinationBtn.innerHTML = '📝 配置目的地';
        configDestinationBtn.onclick = () => {
            showDestinationConfigModal(tempSettings);
        };

        // 配置备注按钮
        const configNoteBtn = document.createElement('button');
        configNoteBtn.type = 'button';
        configNoteBtn.className = 'ant-btn ant-btn-link';
        configNoteBtn.style.cssText = `
            margin-left: 8px;
            padding: 0 8px;
            font-size: 12px;
            color: #1890ff;
            display: ${tempSettings.enableDestinationMatch ? 'inline-block' : 'none'};
        `;
        configNoteBtn.innerHTML = '📝 配置备注';
        configNoteBtn.onclick = () => {
            showNoteConfigModal(tempSettings);
        };

        destinationMatchContainer.appendChild(destinationMatchSwitch);
        destinationMatchContainer.appendChild(configDestinationBtn);
        destinationMatchContainer.appendChild(configNoteBtn);

        // 自动刷新设置区域
        const autoRefreshContainer = document.createElement('div');
        autoRefreshContainer.style.cssText = 'margin-bottom: 16px;';

        // 自动刷新开关
        const autoRefreshSwitch = createSettingSwitch(
            '自动刷新运单',
            tempSettings.enableAutoRefresh,
            (checked) => {
                tempSettings.enableAutoRefresh = checked;
                console.log('临时设置更新 - 自动刷新运单:', checked);

                // 只更新UI显示,不实际应用设置
                if (checked) {
                    autoRefreshIntervalInput.style.display = 'block';
                } else {
                    autoRefreshIntervalInput.style.display = 'none';
                }
            }
        );

        // 刷新间隔输入框
        const autoRefreshIntervalInput = document.createElement('div');
        autoRefreshIntervalInput.style.cssText = `
            margin-top: 8px;
            margin-left: 24px;
            display: ${tempSettings.enableAutoRefresh ? 'block' : 'none'};
        `;
        autoRefreshIntervalInput.innerHTML = `
            <div style="display: flex; align-items: center;">
                <span style="margin-right: 8px;">刷新间隔:</span>
                <input type="number"
                    class="ant-input"
                    style="width: 80px;"
                    min="1"
                    max="3600"
                    value="${tempSettings.refreshInterval}"
                >
                <span style="margin-left: 8px;">秒</span>
            </div>
        `;

        // 监听间隔时间变更
        const intervalInput = autoRefreshIntervalInput.querySelector('input');
        intervalInput.addEventListener('change', (e) => {
            let value = parseInt(e.target.value);
            if (isNaN(value) || value < 1) value = 1;
            if (value > 3600) value = 3600;
            tempSettings.refreshInterval = value;
            e.target.value = value;
            console.log('临时设置更新 - 刷新间隔:', value);
        });

        autoRefreshContainer.appendChild(autoRefreshSwitch);
        autoRefreshContainer.appendChild(autoRefreshIntervalInput);

        // 按钮容器
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'display: flex; justify-content: flex-end; gap: 8px;';

        // 取消按钮
        const cancelBtn = document.createElement('button');
        cancelBtn.className = 'ant-btn';
        cancelBtn.textContent = '取消';
        cancelBtn.onclick = () => {
            console.log('用户取消设置修改,临时设置被丢弃');
            document.body.removeChild(modalContainer);
        };

        // 保存按钮
        const saveBtn = document.createElement('button');
        saveBtn.className = 'ant-btn ant-btn-primary';
        saveBtn.textContent = '保存';
        saveBtn.onclick = () => {
            console.log('=== 开始保存设置 ===');
            console.log('保存前 - 当前settings:', JSON.stringify(settings, null, 2));
            console.log('保存后 - 应用后的settings:', JSON.stringify(tempSettings, null, 2));

            // 应用临时设置到实际设置
            const oldSettings = { ...settings };
            settings = { ...tempSettings };

            // 立即保存设置
            saveSettings();

            // 验证保存是否成功
            setTimeout(() => {
                console.log('验证保存结果:');
                const currentStorageSettings = localStorage.getItem(SETTINGS_KEY);
                console.log('localStorage中的当前设置:', currentStorageSettings);
                console.log('=== 保存设置完成 ===');
            }, 100);

            // 检查需要特殊处理的设置变更
            if (oldSettings.skipGrabConfirm !== settings.skipGrabConfirm && isOnGrabOrderTab()) {
                setupGrabButtons();
            }

            if (oldSettings.enableAutoRefresh !== settings.enableAutoRefresh) {
                const pauseBtn = document.querySelector('.refresh-pause-btn');
                if (pauseBtn) {
                    pauseBtn.style.display = settings.enableAutoRefresh ? 'inline-flex' : 'none';
                }

                if (settings.enableAutoRefresh) {
                    if (window.autoRefreshControl) {
                        window.autoRefreshControl.start();
                    }
                } else {
                    if (window.autoRefreshControl) {
                        window.autoRefreshControl.stop();
                    }
                    isRefreshPaused = false;
                }
            }

            if (oldSettings.refreshInterval !== settings.refreshInterval && settings.enableAutoRefresh && window.autoRefreshControl) {
                window.autoRefreshControl.start();
            }

            // 处理目的地匹配功能的状态变化
            if (oldSettings.enableDestinationMatch !== settings.enableDestinationMatch) {
                if (settings.enableDestinationMatch && destinationList.length > 0) {
                    createMatchInfoPanel();
                } else {
                    // 关闭目的地匹配功能,清理相关状态
                    matchedOrders.clear();
                    if (matchInfoPanel) {
                        matchInfoPanel.style.display = 'none';
                    }
                }
            }

            document.body.removeChild(modalContainer);
            console.log('设置已保存并应用,无需刷新页面');

            // 显示保存成功提示
            const toast = document.createElement('div');
            toast.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #52c41a;
                color: white;
                padding: 12px 20px;
                border-radius: 6px;
                z-index: 10000;
                font-size: 14px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            `;
            toast.textContent = '✅ 设置已保存';
            document.body.appendChild(toast);

            setTimeout(() => {
                if (toast.parentNode) {
                    toast.parentNode.removeChild(toast);
                }
            }, 3000);
        };

        // 组装模态框
        buttonContainer.appendChild(cancelBtn);
        buttonContainer.appendChild(saveBtn);
        settingsContent.appendChild(autoGrabSwitch);
        settingsContent.appendChild(countdownSwitch);
        settingsContent.appendChild(skipConfirmSwitch);
        settingsContent.appendChild(destinationMatchContainer);
        settingsContent.appendChild(autoRefreshContainer);
        modalContent.appendChild(title);
        modalContent.appendChild(settingsContent);
        modalContent.appendChild(buttonContainer);
        modalContainer.appendChild(modalContent);

        // 显示模态框
        document.body.appendChild(modalContainer);

        console.log('设置弹窗已打开,当前设置:', settings);
    }

    // 显示目的地配置弹窗
    function showDestinationConfigModal(parentSettings) {
        // 创建模态框容器
        const modalContainer = document.createElement('div');
        modalContainer.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 10000;
        `;

        // 创建模态框内容
        const modalContent = document.createElement('div');
        modalContent.style.cssText = `
            background-color: white;
            padding: 24px;
            border-radius: 8px;
            min-width: 500px;
            max-width: 80%;
            max-height: 80vh;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            display: flex;
            flex-direction: column;
        `;

        // 标题
        const title = document.createElement('h3');
        title.style.cssText = 'margin: 0 0 16px 0; font-size: 16px; font-weight: 500;';
        title.textContent = '配置目的地匹配列表';

        // 列表容器
        const listContainer = document.createElement('div');
        listContainer.style.cssText = `
            flex: 1;
            overflow-y: auto;
            max-height: 400px;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            margin-bottom: 16px;
        `;

        // 添加目的地输入框
        const inputContainer = document.createElement('div');
        inputContainer.style.cssText = 'display: flex; gap: 8px; margin-bottom: 16px; align-items: center;';

        const destinationInput = document.createElement('input');
        destinationInput.type = 'text';
        destinationInput.className = 'ant-input';
        destinationInput.placeholder = '输入目的地名称(支持模糊匹配)';
        destinationInput.style.cssText = 'flex: 1;';

        const addBtn = document.createElement('button');
        addBtn.type = 'button';
        addBtn.className = 'ant-btn ant-btn-primary';
        addBtn.textContent = '添加';

        inputContainer.appendChild(destinationInput);
        inputContainer.appendChild(addBtn);

        // 渲染目的地列表
        function renderDestinationList() {
            listContainer.innerHTML = '';

            if (destinationList.length === 0) {
                const emptyDiv = document.createElement('div');
                emptyDiv.style.cssText = `
                    padding: 40px 20px;
                    text-align: center;
                    color: #999;
                    font-size: 14px;
                `;
                emptyDiv.innerHTML = `
                    <div style="font-size: 32px; margin-bottom: 12px;">📍</div>
                    <div>暂无配置的目的地</div>
                    <div style="font-size: 12px; margin-top: 8px;">请在上方输入框中添加目的地</div>
                `;
                listContainer.appendChild(emptyDiv);
                return;
            }

            destinationList.forEach((destination, index) => {
                const item = document.createElement('div');
                item.style.cssText = `
                    display: flex;
                    align-items: center;
                    padding: 12px 16px;
                    border-bottom: 1px solid #f0f0f0;
                    transition: background-color 0.2s;
                `;
                item.addEventListener('mouseenter', () => item.style.backgroundColor = '#f5f5f5');
                item.addEventListener('mouseleave', () => item.style.backgroundColor = 'transparent');

                // 序号
                const indexDiv = document.createElement('div');
                indexDiv.style.cssText = `
                    width: 30px;
                    height: 30px;
                    border-radius: 50%;
                    background: #1890ff;
                    color: white;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    font-size: 12px;
                    font-weight: bold;
                    margin-right: 12px;
                `;
                indexDiv.textContent = index + 1;

                // 目的地名称
                const nameDiv = document.createElement('div');
                nameDiv.style.cssText = `
                    flex: 1;
                    font-size: 14px;
                    color: #262626;
                `;
                nameDiv.textContent = destination;

                // 删除按钮
                const deleteBtn = document.createElement('button');
                deleteBtn.type = 'button';
                deleteBtn.className = 'ant-btn ant-btn-text ant-btn-sm';
                deleteBtn.style.cssText = `
                    color: #ff4d4f;
                    border: none;
                    padding: 4px 8px;
                    font-size: 12px;
                `;
                deleteBtn.innerHTML = '🗑️ 删除';
                deleteBtn.onclick = () => {
                    destinationList.splice(index, 1);
                    renderDestinationList();
                };

                item.appendChild(indexDiv);
                item.appendChild(nameDiv);
                item.appendChild(deleteBtn);
                listContainer.appendChild(item);
            });
        }

        // 添加目的地功能
        addBtn.onclick = () => {
            const destination = destinationInput.value.trim();
            if (!destination) {
                alert('请输入目的地名称');
                return;
            }
            if (destinationList.includes(destination)) {
                alert('该目的地已存在');
                return;
            }
            destinationList.push(destination);
            destinationInput.value = '';
            renderDestinationList();
        };

        // 支持回车添加
        destinationInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                addBtn.click();
            }
        });

        // 按钮容器
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'display: flex; justify-content: space-between; align-items: center; gap: 8px;';

        const leftButtons = document.createElement('div');
        leftButtons.style.cssText = 'display: flex; gap: 8px;';

        const rightButtons = document.createElement('div');
        rightButtons.style.cssText = 'display: flex; gap: 8px;';

        // 取消按钮
        const cancelBtn = document.createElement('button');
        cancelBtn.className = 'ant-btn';
        cancelBtn.textContent = '取消';
        cancelBtn.onclick = () => {
            // 关闭当前设置弹窗并打开目的地配置弹窗
            document.body.removeChild(modalContainer);
        };

        // 清空按钮
        const clearBtn = document.createElement('button');
        clearBtn.className = 'ant-btn';
        clearBtn.style.color = '#ff4d4f';
        clearBtn.textContent = '清空列表';
        clearBtn.onclick = () => {
            if (confirm('确定要清空所有目的地吗?')) {
                destinationList.length = 0;
                renderDestinationList();
            }
        };

        // 保存按钮
        const saveBtn = document.createElement('button');
        saveBtn.className = 'ant-btn ant-btn-primary';
        saveBtn.textContent = '保存并应用设置';
        saveBtn.onclick = () => {
            // 先保存目的地列表
            saveDestinationList();

            // 应用父级临时设置到实际设置
            console.log('应用临时设置:', parentSettings);
            const oldSettings = { ...settings };
            settings = { ...parentSettings };
            saveSettings();

            // 检查需要特殊处理的设置变更
            if (oldSettings.skipGrabConfirm !== settings.skipGrabConfirm && isOnGrabOrderTab()) {
                setupGrabButtons();
            }

            if (oldSettings.enableAutoRefresh !== settings.enableAutoRefresh) {
                const pauseBtn = document.querySelector('.refresh-pause-btn');
                if (pauseBtn) {
                    pauseBtn.style.display = settings.enableAutoRefresh ? 'inline-flex' : 'none';
                }

                if (settings.enableAutoRefresh) {
                    if (window.autoRefreshControl) {
                        window.autoRefreshControl.start();
                    }
                } else {
                    if (window.autoRefreshControl) {
                        window.autoRefreshControl.stop();
                    }
                    isRefreshPaused = false;
                }
            }

            if (oldSettings.refreshInterval !== settings.refreshInterval && settings.enableAutoRefresh && window.autoRefreshControl) {
                window.autoRefreshControl.start();
            }

            // 如果启用了目的地匹配,初始化面板
            if (settings.enableDestinationMatch && destinationList.length > 0) {
                createMatchInfoPanel();
            }

            document.body.removeChild(modalContainer);
            console.log('目的地配置和设置已保存:', destinationList, settings);

            // 显示保存成功提示
            const toast = document.createElement('div');
            toast.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #52c41a;
                color: white;
                padding: 12px 20px;
                border-radius: 6px;
                z-index: 10000;
                font-size: 14px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            `;

            if (settings.enableDestinationMatch && destinationList.length > 0) {
                toast.innerHTML = `
                    <div style="font-weight: 500; margin-bottom: 4px;">✅ 设置已保存</div>
                    <div style="font-size: 12px; opacity: 0.9;">已配置 ${destinationList.length} 个目的地,将自动匹配抢单</div>
                `;
            } else {
                toast.textContent = '✅ 设置已保存';
            }

            document.body.appendChild(toast);

            setTimeout(() => {
                if (toast.parentNode) {
                    toast.parentNode.removeChild(toast);
                }
            }, 3000);

            // 刷新页面以完全应用新设置
            console.log('设置已保存并应用,页面将刷新');
            setTimeout(() => location.reload(), 1000);
        };

        leftButtons.appendChild(cancelBtn);

        rightButtons.appendChild(clearBtn);
        rightButtons.appendChild(saveBtn);
        buttonContainer.appendChild(leftButtons);
        buttonContainer.appendChild(rightButtons);

        // 组装模态框
        modalContent.appendChild(title);
        modalContent.appendChild(inputContainer);
        modalContent.appendChild(listContainer);
        modalContent.appendChild(buttonContainer);
        modalContainer.appendChild(modalContent);

        // 初始渲染列表
        renderDestinationList();

        // 点击遮罩层关闭弹窗
        modalContainer.addEventListener('click', (e) => {
            if (e.target === modalContainer) {
                backBtn.click(); // 相当于返回设置
            }
        });

        // 显示模态框
        document.body.appendChild(modalContainer);

        // 聚焦到输入框
        setTimeout(() => destinationInput.focus(), 100);
    }

    // 显示备注配置弹窗
    function showNoteConfigModal(parentSettings) {
        // 创建模态框容器
        const modalContainer = document.createElement('div');
        modalContainer.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
            display: flex;
            justify-content: center;
            align-items: center;
            z-index: 10000;
        `;

        // 创建模态框内容
        const modalContent = document.createElement('div');
        modalContent.style.cssText = `
            background-color: white;
            padding: 24px;
            border-radius: 8px;
            min-width: 500px;
            max-width: 600px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            max-height: 70vh;
            overflow-y: auto;
        `;

        // 标题
        const title = document.createElement('h3');
        title.style.cssText = 'margin: 0 0 16px 0; font-size: 16px; font-weight: 500;';
        title.textContent = '备注配置';

        // 创建临时配置副本
        let tempNoteConfig = {
            mode: noteConfig.mode || 'whitelist',
            whitelist: [...(noteConfig.whitelist || [])],
            blacklist: [...(noteConfig.blacklist || [])]
        };

        // 模式选择区域
        const modeContainer = document.createElement('div');
        modeContainer.style.cssText = 'margin-bottom: 16px;';

        const modeLabel = document.createElement('div');
        modeLabel.style.cssText = 'margin-bottom: 8px; font-weight: 500; color: #262626;';
        modeLabel.textContent = '备注匹配模式:';

        const modeRadioContainer = document.createElement('div');
        modeRadioContainer.style.cssText = 'display: flex; gap: 16px;';

        // 白名单选项
        const whitelistRadioContainer = document.createElement('label');
        whitelistRadioContainer.style.cssText = 'display: flex; align-items: center; cursor: pointer;';

        const whitelistRadio = document.createElement('input');
        whitelistRadio.type = 'radio';
        whitelistRadio.name = 'noteMode';
        whitelistRadio.value = 'whitelist';
        whitelistRadio.checked = tempNoteConfig.mode === 'whitelist';
        whitelistRadio.style.cssText = 'margin-right: 6px;';

        const whitelistLabel = document.createElement('span');
        whitelistLabel.textContent = '白名单(命中则自动抢单)';
        whitelistLabel.style.color = '#52c41a';

        whitelistRadioContainer.appendChild(whitelistRadio);
        whitelistRadioContainer.appendChild(whitelistLabel);

        // 黑名单选项
        const blacklistRadioContainer = document.createElement('label');
        blacklistRadioContainer.style.cssText = 'display: flex; align-items: center; cursor: pointer;';

        const blacklistRadio = document.createElement('input');
        blacklistRadio.type = 'radio';
        blacklistRadio.name = 'noteMode';
        blacklistRadio.value = 'blacklist';
        blacklistRadio.checked = tempNoteConfig.mode === 'blacklist';
        blacklistRadio.style.cssText = 'margin-right: 6px;';

        const blacklistLabel = document.createElement('span');
        blacklistLabel.textContent = '黑名单(命中则不抢单)';
        blacklistLabel.style.color = '#ff4d4f';

        blacklistRadioContainer.appendChild(blacklistRadio);
        blacklistRadioContainer.appendChild(blacklistLabel);

        modeRadioContainer.appendChild(whitelistRadioContainer);
        modeRadioContainer.appendChild(blacklistRadioContainer);

        modeContainer.appendChild(modeLabel);
        modeContainer.appendChild(modeRadioContainer);

        // 关键字输入区域
        const inputContainer = document.createElement('div');
        inputContainer.style.cssText = 'margin-bottom: 16px;';

        const inputLabel = document.createElement('div');
        inputLabel.style.cssText = 'margin-bottom: 8px; font-weight: 500; color: #262626;';
        inputLabel.textContent = '添加关键字:';

        const inputGroup = document.createElement('div');
        inputGroup.style.cssText = 'display: flex; gap: 8px;';

        const keywordInput = document.createElement('input');
        keywordInput.type = 'text';
        keywordInput.className = 'ant-input';
        keywordInput.placeholder = '输入备注关键字';
        keywordInput.style.cssText = 'flex: 1; padding: 8px 12px;';

        const addBtn = document.createElement('button');
        addBtn.type = 'button';
        addBtn.className = 'ant-btn ant-btn-primary';
        addBtn.textContent = '添加';
        addBtn.style.cssText = 'padding: 8px 16px;';

        inputGroup.appendChild(keywordInput);
        inputGroup.appendChild(addBtn);

        inputContainer.appendChild(inputLabel);
        inputContainer.appendChild(inputGroup);

        // 关键字列表显示区域
        const listContainer = document.createElement('div');
        listContainer.style.cssText = 'margin-bottom: 20px;';

        const listLabel = document.createElement('div');
        listLabel.style.cssText = 'margin-bottom: 8px; font-weight: 500; color: #262626;';

        const keywordListContainer = document.createElement('div');
        keywordListContainer.style.cssText = `
            min-height: 60px;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            padding: 12px;
            background: #fafafa;
            display: flex;
            flex-wrap: wrap;
            gap: 8px;
            align-items: flex-start;
        `;

        listContainer.appendChild(listLabel);
        listContainer.appendChild(keywordListContainer);

        // 渲染关键字列表
        function renderKeywordList() {
            const currentList = tempNoteConfig.mode === 'whitelist' ? tempNoteConfig.whitelist : tempNoteConfig.blacklist;
            const modeColor = tempNoteConfig.mode === 'whitelist' ? '#52c41a' : '#ff4d4f';
            
            listLabel.textContent = `${tempNoteConfig.mode === 'whitelist' ? '白名单' : '黑名单'}关键字 (${currentList.length}):`;
            listLabel.style.color = modeColor;

            keywordListContainer.innerHTML = '';

            if (currentList.length === 0) {
                const emptyTip = document.createElement('div');
                emptyTip.style.cssText = 'color: #999; font-size: 14px; width: 100%; text-align: center; padding: 20px;';
                emptyTip.textContent = `暂无${tempNoteConfig.mode === 'whitelist' ? '白名单' : '黑名单'}关键字`;
                keywordListContainer.appendChild(emptyTip);
                return;
            }

            currentList.forEach((keyword, index) => {
                const keywordTag = document.createElement('div');
                keywordTag.style.cssText = `
                    display: inline-flex;
                    align-items: center;
                    background: ${tempNoteConfig.mode === 'whitelist' ? '#f6ffed' : '#fff2f0'};
                    border: 1px solid ${tempNoteConfig.mode === 'whitelist' ? '#b7eb8f' : '#ffccc7'};
                    color: ${modeColor};
                    padding: 4px 8px;
                    border-radius: 4px;
                    font-size: 12px;
                    gap: 6px;
                `;

                const keywordText = document.createElement('span');
                keywordText.textContent = keyword;

                const removeBtn = document.createElement('button');
                removeBtn.style.cssText = `
                    background: none;
                    border: none;
                    color: ${modeColor};
                    cursor: pointer;
                    padding: 0;
                    font-size: 14px;
                    line-height: 1;
                    opacity: 0.7;
                `;
                removeBtn.innerHTML = '✕';
                removeBtn.title = '移除关键字';

                removeBtn.onclick = () => {
                    if (tempNoteConfig.mode === 'whitelist') {
                        tempNoteConfig.whitelist.splice(index, 1);
                    } else {
                        tempNoteConfig.blacklist.splice(index, 1);
                    }
                    renderKeywordList();
                };

                keywordTag.appendChild(keywordText);
                keywordTag.appendChild(removeBtn);
                keywordListContainer.appendChild(keywordTag);
            });
        }

        // 添加关键字功能
        function addKeyword() {
            const keyword = keywordInput.value.trim();
            if (!keyword) return;

            const currentList = tempNoteConfig.mode === 'whitelist' ? tempNoteConfig.whitelist : tempNoteConfig.blacklist;
            
            if (currentList.includes(keyword)) {
                keywordInput.style.borderColor = '#ff4d4f';
                setTimeout(() => {
                    keywordInput.style.borderColor = '';
                }, 2000);
                return;
            }

            currentList.push(keyword);
            keywordInput.value = '';
            renderKeywordList();
        }

        // 事件绑定
        addBtn.onclick = addKeyword;
        keywordInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                e.preventDefault();
                addKeyword();
            }
        });

        // 模式切换事件
        whitelistRadio.addEventListener('change', () => {
            if (whitelistRadio.checked) {
                tempNoteConfig.mode = 'whitelist';
                renderKeywordList();
            }
        });

        blacklistRadio.addEventListener('change', () => {
            if (blacklistRadio.checked) {
                tempNoteConfig.mode = 'blacklist';
                renderKeywordList();
            }
        });

        // 按钮容器
        const buttonContainer = document.createElement('div');
        buttonContainer.style.cssText = 'display: flex; justify-content: flex-end; gap: 8px; margin-top: 20px;';

        // 返回按钮
        const backBtn = document.createElement('button');
        backBtn.className = 'ant-btn';
        backBtn.textContent = '返回';
        backBtn.onclick = () => {
            document.body.removeChild(modalContainer);
        };

        // 保存按钮
        const saveBtn = document.createElement('button');
        saveBtn.className = 'ant-btn ant-btn-primary';
        saveBtn.textContent = '保存';
        saveBtn.onclick = () => {
            console.log('保存备注配置:', tempNoteConfig);
            
            // 应用临时配置到全局配置
            noteConfig = { ...tempNoteConfig };
            saveNoteConfig();

            // 显示保存成功提示
            const toast = document.createElement('div');
            toast.style.cssText = `
                position: fixed;
                top: 20px;
                right: 20px;
                background: #52c41a;
                color: white;
                padding: 12px 20px;
                border-radius: 6px;
                z-index: 10001;
                font-size: 14px;
                box-shadow: 0 2px 8px rgba(0,0,0,0.15);
            `;
            toast.textContent = '✅ 备注配置已保存';
            document.body.appendChild(toast);

            setTimeout(() => {
                if (toast.parentNode) {
                    toast.parentNode.removeChild(toast);
                }
            }, 3000);

            // 关闭弹窗并返回设置
            backBtn.click();
        };

        // 组装模态框
        buttonContainer.appendChild(backBtn);
        buttonContainer.appendChild(saveBtn);
        modalContent.appendChild(title);
        modalContent.appendChild(modeContainer);
        modalContent.appendChild(inputContainer);
        modalContent.appendChild(listContainer);
        modalContent.appendChild(buttonContainer);
        modalContainer.appendChild(modalContent);

        // 初始渲染列表
        renderKeywordList();

        // 点击遮罩层关闭弹窗
        modalContainer.addEventListener('click', (e) => {
            if (e.target === modalContainer) {
                backBtn.click(); // 相当于返回设置
            }
        });

        // 显示模态框
        document.body.appendChild(modalContainer);

        // 聚焦到输入框
        setTimeout(() => keywordInput.focus(), 100);
    }

    // 创建浮动信息展示面板
    function createMatchInfoPanel() {
        // 如果已存在面板则先移除
        if (matchInfoPanel && matchInfoPanel.parentNode) {
            matchInfoPanel.parentNode.removeChild(matchInfoPanel);
        }

        // 创建浮动面板
        matchInfoPanel = document.createElement('div');
        matchInfoPanel.style.cssText = `
            position: fixed;
            top: 80px;
            right: 20px;
            width: 320px;
            max-height: 500px;
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(8px);
            border: 1px solid rgba(217, 217, 217, 0.6);
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            z-index: 9000;
            overflow: hidden;
            display: none;
            transition: all 0.3s ease;
        `;

        // 面板标题
        const header = document.createElement('div');
        header.style.cssText = `
            padding: 12px 16px;
            background: rgba(24, 144, 255, 0.1);
            border-bottom: 1px solid rgba(217, 217, 217, 0.3);
            font-size: 14px;
            font-weight: 500;
            color: #1890ff;
            display: flex;
            align-items: center;
            justify-content: space-between;
        `;
        header.innerHTML = `
            <span>🎯 目的地匹配抢单</span>
            <span class="match-count">0</span>
        `;

        // 面板内容
        const content = document.createElement('div');
        content.className = 'match-panel-content';
        content.style.cssText = `
            max-height: 400px;
            overflow-y: auto;
        `;

        matchInfoPanel.appendChild(header);
        matchInfoPanel.appendChild(content);
        document.body.appendChild(matchInfoPanel);

        console.log('浮动信息面板已创建');
        return matchInfoPanel;
    }

    // 更新浮动面板内容
    function updateMatchInfoPanel() {
        if (!settings.enableDestinationMatch || destinationList.length === 0) {
            if (matchInfoPanel) {
                matchInfoPanel.style.display = 'none';
            }
            return;
        }

        if (!matchInfoPanel) {
            createMatchInfoPanel();
        }

        const content = matchInfoPanel.querySelector('.match-panel-content');
        const countElement = matchInfoPanel.querySelector('.match-count');

        if (matchedOrders.size === 0) {
            matchInfoPanel.style.display = 'none';
            return;
        }

        // 显示面板
        matchInfoPanel.style.display = 'block';
        countElement.textContent = matchedOrders.size;

        // 清空内容
        content.innerHTML = '';

        // 渲染匹配的订单
        matchedOrders.forEach((orderInfo, orderId) => {
            const item = document.createElement('div');
            item.style.cssText = `
                padding: 12px 16px;
                border-bottom: 1px solid rgba(240, 240, 240, 0.5);
                transition: background-color 0.2s;
            `;
            item.addEventListener('mouseenter', () => item.style.backgroundColor = 'rgba(245, 245, 245, 0.3)');
            item.addEventListener('mouseleave', () => item.style.backgroundColor = 'transparent');

            // 订单信息
            const orderDiv = document.createElement('div');
            orderDiv.style.cssText = 'margin-bottom: 8px;';
            orderDiv.innerHTML = `
                <div style="font-size: 14px; font-weight: 500; color: #262626; margin-bottom: 4px;">
                    ${orderInfo.code || orderId}
                </div>
                <div style="font-size: 12px; color: #666; margin-bottom: 2px;">
                    📍 目的地: ${orderInfo.destinationName || '未知'}
                </div>
                ${orderInfo.note ? `<div style="font-size: 12px; color: #999;">💬 ${orderInfo.note}</div>` : ''}
            `;

            // 状态显示
            const statusDiv = document.createElement('div');
            statusDiv.className = `match-status-${orderId}`;
            statusDiv.style.cssText = `
                font-size: 12px;
                font-weight: 500;
                padding: 2px 8px;
                border-radius: 4px;
                text-align: center;
            `;

            // 根据订单状态显示不同内容
            if (orderInfo.grabStatus === 'pending') {
                statusDiv.textContent = '⏳ 等待抢单时间';
                statusDiv.style.background = 'rgba(250, 173, 20, 0.1)';
                statusDiv.style.color = '#faad14';
            } else if (orderInfo.grabStatus === 'grabbing') {
                statusDiv.textContent = '🚀 抢单中...';
                statusDiv.style.background = 'rgba(24, 144, 255, 0.1)';
                statusDiv.style.color = '#1890ff';
            } else if (orderInfo.grabStatus === 'success') {
                statusDiv.textContent = '✅ 抢单成功';
                statusDiv.style.background = 'rgba(82, 196, 26, 0.1)';
                statusDiv.style.color = '#52c41a';
            } else if (orderInfo.grabStatus === 'failed') {
                statusDiv.textContent = '❌ 抢单失败';
                statusDiv.style.background = 'rgba(245, 34, 45, 0.1)';
                statusDiv.style.color = '#f5222d';
            }

            item.appendChild(orderDiv);
            item.appendChild(statusDiv);
            content.appendChild(item);
        });
    }

    // 更新匹配订单状态
    function updateMatchOrderStatus(orderId, status) {
        if (matchedOrders.has(orderId)) {
            const orderInfo = matchedOrders.get(orderId);
            orderInfo.grabStatus = status;
            matchedOrders.set(orderId, orderInfo);
            updateMatchInfoPanel();
        }
    }

    // 更新暂停按钮状态
    function updatePauseButton(button) {
        button.innerHTML = `
            <span role="img" aria-label="${isRefreshPaused ? 'play-circle' : 'pause-circle'}" 
                  class="anticon anticon-${isRefreshPaused ? 'play-circle' : 'pause-circle'}"
                  style="margin-right: 4px;">
                <svg viewBox="64 64 896 896" focusable="false" data-icon="${isRefreshPaused ? 'play-circle' : 'pause-circle'}" 
                     width="1em" height="1em" fill="currentColor" aria-hidden="true">
                    ${isRefreshPaused
                ? '<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm-88-532h-48c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8zm224 0h-48c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8h48c4.4 0 8-3.6 8-8V360c0-4.4-3.6-8-8-8z"></path>'
                : '<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372zm-80-544c-4.4 0-8 3.6-8 8v304c0 4.4 3.6 8 8 8h208c4.4 0 8-3.6 8-8V348c0-4.4-3.6-8-8-8H432z"></path>'}
                </svg>
            </span>
            <span>${isRefreshPaused ? '继续' : '暂停'}</span>
        `;
        button.title = isRefreshPaused ? '继续自动刷新' : '暂停自动刷新';
        button.style.color = isRefreshPaused ? '#1890ff' : '#ff4d4f';
    }

    // 自动刷新功能
    function setupAutoRefresh() {
        // 查找刷新按钮
        const refreshBtn = document.querySelector("#\\35 6x3i7oYVrcCd393 > div > div > div > div.dispatch___3GhUt > div.container___1d0D1 > div > div.ant-card-head > div > div > div > button");
        if (!refreshBtn) {
            console.warn('未找到刷新按钮');
            return;
        }

        // 创建显示和控制区域
        const statusContainer = document.createElement('div');
        statusContainer.style.cssText = `
            display: inline-flex;
            align-items: center;
            margin-right: 12px;
            font-size: 12px;
            color: rgba(0, 0, 0, 0.45);
        `;

        // 状态显示
        const statusDisplay = document.createElement('div');
        statusDisplay.style.cssText = 'display: inline-flex; align-items: center; margin-right: 8px;';
        statusDisplay.innerHTML = `
            <span class="last-refresh" style="margin-right: 12px;"></span>
            <span class="next-refresh"></span>
        `;

        // 暂停/继续按钮
        const pauseBtn = document.createElement('button');
        pauseBtn.type = 'button';
        pauseBtn.className = 'ant-btn ant-btn-link refresh-pause-btn';
        pauseBtn.style.cssText = `
            padding: 0 8px;
            height: 24px;
            font-size: 14px;
            display: ${settings.enableAutoRefresh ? 'inline-flex' : 'none'};
            align-items: center;
            color: #1890ff;
        `;
        updatePauseButton(pauseBtn);

        pauseBtn.onclick = () => {
            isRefreshPaused = !isRefreshPaused;
            updatePauseButton(pauseBtn);

            if (isRefreshPaused) {
                if (autoRefreshTimer) {
                    clearInterval(autoRefreshTimer);
                    autoRefreshTimer = null;
                }
            } else {
                startAutoRefresh();
            }
        };

        statusContainer.appendChild(statusDisplay);
        statusContainer.appendChild(pauseBtn);

        // 插入状态显示
        refreshBtn.parentNode.insertBefore(statusContainer, refreshBtn);

        // 更新显示函数
        function updateRefreshStatus() {
            const lastRefreshEl = statusContainer.querySelector('.last-refresh');
            const nextRefreshEl = statusContainer.querySelector('.next-refresh');

            if (lastRefreshTime) {
                lastRefreshEl.textContent = `上次刷新: ${lastRefreshTime.toLocaleTimeString()}`;
            }

            if (settings.enableAutoRefresh) {
                const now = Date.now();
                const nextRefreshTime = lastRefreshTime ? lastRefreshTime.getTime() + settings.refreshInterval * 1000 : now + settings.refreshInterval * 1000;
                const timeLeft = Math.max(0, Math.floor((nextRefreshTime - now) / 1000));

                if (isRefreshPaused) {
                    nextRefreshEl.textContent = '自动刷新已暂停';
                    nextRefreshEl.style.color = '#ff4d4f';
                } else {
                    nextRefreshEl.textContent = `下次刷新: ${timeLeft}秒`;
                    nextRefreshEl.style.color = 'inherit';
                }
            } else {
                nextRefreshEl.textContent = '';
                nextRefreshEl.style.color = 'inherit';
            }
        }

        // 执行刷新
        function doRefresh() {
            lastRefreshTime = new Date();
            refreshBtn.click();
            updateRefreshStatus();
        }

        // 设置自动刷新定时器
        function startAutoRefresh() {
            if (autoRefreshTimer) {
                clearInterval(autoRefreshTimer);
            }

            if (settings.enableAutoRefresh) {
                autoRefreshTimer = setInterval(() => {
                    doRefresh();
                }, settings.refreshInterval * 1000);

                // 更新显示的定时器
                setInterval(updateRefreshStatus, 1000);
            }
        }

        // 停止自动刷新
        function stopAutoRefresh() {
            if (autoRefreshTimer) {
                clearInterval(autoRefreshTimer);
                autoRefreshTimer = null;
            }
            lastRefreshTime = null;
            updateRefreshStatus();
        }

        // 根据设置状态初始化
        if (settings.enableAutoRefresh) {
            startAutoRefresh();
        }

        // 导出函数供设置变更时使用
        window.autoRefreshControl = {
            start: startAutoRefresh,
            stop: stopAutoRefresh
        };
    }

    // 创建设置开关
    function createSettingSwitch(label, checked, onChange) {
        const container = document.createElement('div');
        container.style.cssText = 'display: flex; align-items: center; margin-bottom: 16px;';

        const switchLabel = document.createElement('span');
        switchLabel.style.cssText = 'margin-right: 8px;';
        switchLabel.textContent = label;

        const switchContainer = document.createElement('button');
        switchContainer.className = `ant-switch${checked ? ' ant-switch-checked' : ''}`;
        switchContainer.style.cssText = 'position: relative; display: inline-block; width: 44px; height: 22px;';

        const switchHandle = document.createElement('span');
        switchHandle.className = 'ant-switch-handle';

        switchContainer.appendChild(switchHandle);

        // 维护内部状态以确保准确性
        let currentState = checked;

        switchContainer.onclick = () => {
            // 切换状态
            currentState = !currentState;

            // 更新UI
            if (currentState) {
                switchContainer.classList.add('ant-switch-checked');
            } else {
                switchContainer.classList.remove('ant-switch-checked');
            }

            // 调用回调函数
            onChange(currentState);

            console.log(`开关 "${label}" 状态变更为: ${currentState}`);
        };

        container.appendChild(switchLabel);
        container.appendChild(switchContainer);

        return container;
    }

    // NTP时间同步功能
    async function syncNtpTime() {
        if (isNtpSynced || ntpSyncRetries >= MAX_NTP_RETRIES) {
            return;
        }

        console.log(`开始NTP时间同步,第 ${ntpSyncRetries + 1} 次尝试...`);

        for (const server of NTP_SERVERS) {
            try {
                const localTime = Date.now();
                let response, serverTime;

                if (server.includes('worldtimeapi.org')) {
                    // 使用WorldTimeAPI
                    response = await fetch(`https://${server}`, {
                        method: 'GET',
                        cache: 'no-cache'
                    });
                    if (response.ok) {
                        const data = await response.json();
                        serverTime = new Date(data.datetime).getTime();
                    }
                } else if (server.includes('timeapi.io')) {
                    // 使用TimeAPI
                    response = await fetch(`https://${server}`, {
                        method: 'GET',
                        cache: 'no-cache'
                    });
                    if (response.ok) {
                        const data = await response.json();
                        serverTime = new Date(data.dateTime).getTime();
                    }
                } else {
                    // 使用HTTP HEAD请求获取Date头
                    response = await fetch(`https://${server}`, {
                        method: 'HEAD',
                        cache: 'no-cache'
                    });
                    if (response.ok) {
                        const serverTimeStr = response.headers.get('Date');
                        if (serverTimeStr) {
                            serverTime = new Date(serverTimeStr).getTime();
                        }
                    }
                }

                if (serverTime) {
                    const networkDelay = (Date.now() - localTime) / 2; // 估算网络延迟
                    const adjustedServerTime = serverTime + networkDelay;

                    ntpTimeOffset = adjustedServerTime - Date.now();
                    isNtpSynced = true;

                    console.log(`NTP时间同步成功 - 服务器: ${server}`);
                    console.log(`本地时间: ${new Date().toISOString()}`);
                    console.log(`服务器时间: ${new Date(adjustedServerTime).toISOString()}`);
                    console.log(`时间偏移: ${ntpTimeOffset}ms (${ntpTimeOffset > 0 ? '服务器时间较快' : '本地时间较快'})`);

                    return;
                }
            } catch (error) {
                console.warn(`NTP同步失败 - 服务器: ${server}, 错误:`, error.message);
            }
        }

        ntpSyncRetries++;
        if (ntpSyncRetries < MAX_NTP_RETRIES) {
            setTimeout(() => syncNtpTime(), 5000); // 5秒后重试
        } else {
            console.warn('NTP时间同步失败,将使用本地时间');
        }
    }


    // 获取本地时间
    function getLocalTime() {
        return new Date();
    }

    // 获取NTP同步时间
    function getNtpTime() {
        return new Date(Date.now() + ntpTimeOffset);
    }

    // 工具函数:解析时间字符串为Date对象
    function parseTimeString(timeStr) {
        if (!timeStr || timeStr.trim() === '') {
            console.warn('时间字符串为空:', timeStr);
            return null;
        }

        const cleanTimeStr = timeStr.replace(/\s+/g, ' ').trim();
        console.log(`解析时间字符串: "${cleanTimeStr}"`);

        try {
            // 尝试多种时间格式
            let date = null;

            // 格式1: "2025-09-07 18:07:00"
            if (cleanTimeStr.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/)) {
                date = new Date(cleanTimeStr);
            }
            // 格式2: "2025-09-07 18:07" (没有秒)
            else if (cleanTimeStr.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/)) {
                date = new Date(cleanTimeStr + ':00');
            }
            // 格式3: ISO 时间格式
            else if (cleanTimeStr.includes('T')) {
                date = new Date(cleanTimeStr);
            }
            // 格式4: 多行时间格式 "2025-09-07 18:07:00\n时间错误"
            else if (cleanTimeStr.includes('\n')) {
                const firstLine = cleanTimeStr.split('\n')[0].trim();
                if (firstLine.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/)) {
                    date = new Date(firstLine);
                } else if (firstLine.match(/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}$/)) {
                    date = new Date(firstLine + ':00');
                }
            }
            // 其他格式尝试直接解析
            else {
                date = new Date(cleanTimeStr);
            }

            // 检查解析结果
            if (!date || isNaN(date.getTime())) {
                console.error('时间解析结果无效:', cleanTimeStr, date);
                return null;
            }

            console.log(`时间解析成功: "${cleanTimeStr}" -> ${date.toISOString()}`);
            return date;
        } catch (e) {
            console.error('解析时间失败:', cleanTimeStr, e);
            return null;
        }
    }

    // 工具函数:格式化倒计时显示
    function formatCountdown(seconds) {
        // 检查输入有效性
        if (!isFinite(seconds) || isNaN(seconds)) {
            console.error('formatCountdown 接收到无效数字:', seconds);
            return '时间错误';
        }

        if (seconds <= 0) return '已到时间';

        const hours = Math.floor(seconds / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = seconds % 60;

        if (hours > 0) {
            return `${hours}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
        } else {
            return `${minutes}:${secs.toString().padStart(2, '0')}`;
        }
    }

    // 检查是否在抢单页面
    function isOnGrabOrderTab() {
        const activeTab = document.querySelector('.ant-radio-button-wrapper-checked input[value="CAN_GRAB_ORD"]');
        return activeTab !== null;
    }


    // 确保操作列有足够宽度容纳自动抢单按钮
    function ensureOperationColumnWidth() {
        const headers = document.querySelectorAll('.ant-table-header thead th');
        const headerColgroup = document.querySelector('.ant-table-header colgroup');
        const bodyColgroup = document.querySelector('.ant-table-body colgroup');

        if (!headerColgroup || !bodyColgroup) return;

        const cols = headerColgroup.children;
        let operationHeaderIndex = -1;

        headers.forEach((header, index) => {
            if (header.textContent && header.textContent.includes('操作')) {
                operationHeaderIndex = index;
            }
        });

        if (operationHeaderIndex >= 0 && cols[operationHeaderIndex]) {
            const operationCol = cols[operationHeaderIndex];
            const currentWidth = parseInt(operationCol.style.width) || 120;
            // 为操作列增加额外宽度以容纳自动抢单按钮
            const newWidth = Math.max(currentWidth, 200);
            operationCol.style.cssText = `width: ${newWidth}px; min-width: ${newWidth}px;`;

            // 同步更新body colgroup中对应的列
            const bodyOperationCol = bodyColgroup.children[operationHeaderIndex];
            if (bodyOperationCol) {
                bodyOperationCol.style.cssText = `width: ${newWidth}px; min-width: ${newWidth}px;`;
            }

            // 更新对应的表头宽度
            const operationHeader = headers[operationHeaderIndex];
            if (operationHeader) {
                operationHeader.style.width = `${newWidth}px`;
                operationHeader.style.minWidth = `${newWidth}px`;
            }

            console.log(`操作列宽度已更新为: ${newWidth}px`);
        }
    }

    // 为表格行添加倒计时和自动抢单功能
    function processTableRows() {
        const tableBody = document.querySelector('.ant-table-body tbody');
        if (!tableBody) return;
        const rows = tableBody.querySelectorAll('tr[data-row-key]');

        if (isProcessing || !settings.showCountdown) return;
        isProcessing = true;

        try {

            rows.forEach((row) => {
                const rowKey = row.getAttribute('data-row-key');
                if (!rowKey) return;

                const cells = row.querySelectorAll('td');
                if (cells.length < 6) return;

                // 找到"可抢单时间"列
                let grabTimeCell = null;

                cells.forEach((cell, index) => {
                    // 通过查找表头来确定可抢单时间列的位置
                    const headerCells = document.querySelectorAll('.ant-table-header thead th');
                    if (headerCells[index] && headerCells[index].textContent.includes('可抢单时间')) {
                        grabTimeCell = cell;
                        console.log(`运单 ${rowKey} 找到可抢单时间列,索引: ${index}, 内容: "${cell.textContent.trim()}"`);
                    }
                });

                if (!grabTimeCell) {
                    console.warn(`运单 ${rowKey} 未找到可抢单时间列,跳过行处理。可用列数: ${cells.length}`);
                    // 打印所有表头帮助调试
                    const headerCells = document.querySelectorAll('.ant-table-header thead th');
                    headerCells.forEach((header, i) => {
                        console.log(`表头 ${i}: "${header.textContent.trim()}"`);
                    });
                    return;
                }

                const grabTimeText = grabTimeCell.textContent.trim();

                // 检查是否已经处理过这一行
                if (grabTimeCell.querySelector('.countdown-display')) {
                    updateExistingRow(row, rowKey, grabTimeText);
                    return;
                }

                // 直接在可抢单时间列中添加倒计时显示
                console.log(`运单 ${rowKey} 开始添加倒计时到时间列`);
                addCountdownToTimeCell(grabTimeCell, rowKey, grabTimeText);

                // 在操作列添加自动抢单按钮
                addAutoGrabButton(row, rowKey);
            });
        } finally {
            isProcessing = false;
        }
    }

    // 在可抢单时间列中添加倒计时显示
    function addCountdownToTimeCell(grabTimeCell, rowKey, grabTimeText) {
        console.log(`运单 ${rowKey} addCountdownToTimeCell 被调用,原始时间: "${grabTimeText}"`);

        if (!grabTimeCell) {
            console.error(`运单 ${rowKey} grabTimeCell 为空,无法添加倒计时`);
            return;
        }

        // 从时间字符串中提取第一行作为原始时间
        let originalTime = grabTimeText;
        if (grabTimeText.includes('\n')) {
            originalTime = grabTimeText.split('\n')[0].trim();
        }

        console.log(`运单 ${rowKey} 开始重构时间列内容,提取的时间: "${originalTime}"`);
        // 清空原内容,重新构建
        grabTimeCell.innerHTML = '';
        grabTimeCell.style.cssText = 'text-align: center; overflow: hidden; padding: 8px 4px;';

        // 原始时间显示
        const timeDiv = document.createElement('div');
        timeDiv.className = 'grab-time-original';
        timeDiv.style.cssText = 'font-size: 12px; color: #666; line-height: 1.2; margin-bottom: 2px;';
        timeDiv.textContent = originalTime;

        // 倒计时显示
        const countdownDiv = document.createElement('div');
        countdownDiv.className = 'countdown-display';
        countdownDiv.style.cssText = 'font-size: 13px; font-weight: bold; color: #ff4d4f; line-height: 1.2;';
        countdownDiv.textContent = '--';

        grabTimeCell.appendChild(timeDiv);
        grabTimeCell.appendChild(countdownDiv);

        console.log(`运单 ${rowKey} 时间列内容重构完成,开始倒计时`);

        // 开始倒计时
        startCountdown(rowKey, originalTime, grabTimeCell);
    }

    // 更新已存在的行
    function updateExistingRow(row, rowKey, grabTimeText) {
        // 从时间字符串中提取第一行作为原始时间
        let originalTime = grabTimeText;
        if (grabTimeText.includes('\n')) {
            originalTime = grabTimeText.split('\n')[0].trim();
        }

        // 找到可抢单时间列
        let updateGrabTimeCell = null;
        row.querySelectorAll('td').forEach((cell, index) => {
            const headerCells = document.querySelectorAll('.ant-table-header thead th');
            if (headerCells[index] && headerCells[index].textContent.includes('可抢单时间')) {
                updateGrabTimeCell = cell;
            }
        });

        if (updateGrabTimeCell && updateGrabTimeCell.querySelector('.countdown-display') && !autoGrabTasks.has(rowKey)) {
            // 重新开始倒计时(处理数据更新的情况)
            startCountdown(rowKey, originalTime, updateGrabTimeCell);
        }

        // 检查自动抢单按钮状态
        const existingAutoBtn = row.querySelector('.auto-grab-btn');
        const grabTime = parseTimeString(originalTime);

        if (grabTime && !isNaN(grabTime.getTime())) {
            const now = new Date();
            const timeDiff = grabTime.getTime() - now.getTime();

            console.log(`运单 ${rowKey} 更新检查: 时间差=${Math.floor(timeDiff / 1000)}秒, 有按钮=${!!existingAutoBtn}, 有任务=${autoGrabTasks.has(rowKey)}`);

            // 如果时间已到,移除自动抢单按钮
            if (timeDiff <= 0 && existingAutoBtn && !autoGrabTasks.has(rowKey)) {
                existingAutoBtn.remove();
                console.log(`运单 ${rowKey} 时间已到,移除自动抢单按钮`);
            }
            // 如果时间未到且没有按钮,添加按钮
            else if (timeDiff > 0 && !existingAutoBtn && !autoGrabTasks.has(rowKey)) {
                console.log(`运单 ${rowKey} 时间未到且无按钮,添加自动抢单按钮`);
                addAutoGrabButton(row, rowKey);
            }
        } else {
            console.warn(`运单 ${rowKey} 时间解析失败,无法检查按钮状态`);
        }
    }

    // 开始双重倒计时(本地时间和NTP时间)
    function startCountdown(rowKey, grabTimeText, grabTimeCell) {
        // 清除已存在的倒计时
        if (countdownIntervals.has(rowKey)) {
            const existing = countdownIntervals.get(rowKey);
            if (existing.local) clearInterval(existing.local);
            if (existing.ntp) clearInterval(existing.ntp);
        }

        const grabTime = parseTimeString(grabTimeText);
        if (!grabTime) {
            const displayElement = grabTimeCell.querySelector('.countdown-display');
            if (displayElement) {
                displayElement.textContent = '时间错误';
            }
            return;
        }

        // 创建双重显示元素
        const displayElement = grabTimeCell.querySelector('.countdown-display');
        if (!displayElement) {
            console.warn(`运单 ${rowKey} 找不到倒计时显示元素`);
            return;
        }

        // 重构显示元素,支持双重时间显示
        displayElement.innerHTML = '';
        displayElement.style.cssText = 'font-size: 12px; font-weight: bold; line-height: 1.2;';

        // 本地时间倒计时显示
        const localDisplay = document.createElement('div');
        localDisplay.className = 'local-countdown';
        localDisplay.style.cssText = 'color: #ff4d4f; margin-bottom: 2px;';
        localDisplay.title = '基于本地时间的倒计时';

        // NTP时间倒计时显示
        const ntpDisplay = document.createElement('div');
        ntpDisplay.className = 'ntp-countdown';
        ntpDisplay.style.cssText = 'color: #1890ff; font-size: 11px;';
        ntpDisplay.title = '基于NTP同步时间的倒计时';

        displayElement.appendChild(localDisplay);
        if (isNtpSynced && Math.abs(ntpTimeOffset) > 1000) { // 时间差超过1秒才显示NTP倒计时
            displayElement.appendChild(ntpDisplay);
        }

        // 本地时间倒计时更新函数
        const updateLocalCountdown = () => {
            const now = getLocalTime();
            const timeDiff = grabTime.getTime() - now.getTime();
            const secondsLeft = Math.floor(timeDiff / 1000);

            if (secondsLeft <= 0) {
                localDisplay.textContent = '已到时间(本地)';
                localDisplay.style.color = '#52c41a';

                // 清除本地倒计时
                const intervals = countdownIntervals.get(rowKey);
                if (intervals && intervals.local) {
                    clearInterval(intervals.local);
                    intervals.local = null;
                }

                // 检查是否需要移除自动抢单按钮
                checkAndRemoveAutoGrabButton(rowKey, grabTimeCell);
            } else if (!isNaN(secondsLeft) && isFinite(secondsLeft)) {
                localDisplay.textContent = `本地: ${formatCountdown(secondsLeft)}`;
                localDisplay.style.color = '#ff4d4f';
            } else {
                localDisplay.textContent = '本地: 时间错误';
                localDisplay.style.color = '#999';
            }
        };

        // NTP时间倒计时更新函数
        const updateNtpCountdown = () => {
            if (!isNtpSynced) return;

            const now = getNtpTime();
            const timeDiff = grabTime.getTime() - now.getTime();
            const secondsLeft = Math.floor(timeDiff / 1000);

            if (secondsLeft <= 0) {
                ntpDisplay.textContent = '已到时间(NTP)';
                ntpDisplay.style.color = '#52c41a';

                // 清除NTP倒计时
                const intervals = countdownIntervals.get(rowKey);
                if (intervals && intervals.ntp) {
                    clearInterval(intervals.ntp);
                    intervals.ntp = null;
                }

                // 检查是否需要移除自动抢单按钮
                checkAndRemoveAutoGrabButton(rowKey, grabTimeCell);
            } else if (!isNaN(secondsLeft) && isFinite(secondsLeft)) {
                ntpDisplay.textContent = `NTP: ${formatCountdown(secondsLeft)}`;
                ntpDisplay.style.color = '#1890ff';
            } else {
                ntpDisplay.textContent = 'NTP: 时间错误';
                ntpDisplay.style.color = '#999';
            }
        };

        // 立即执行一次
        updateLocalCountdown();
        if (isNtpSynced) {
            updateNtpCountdown();
        }

        // 设置双重定时器
        const localIntervalId = setInterval(updateLocalCountdown, 1000);
        let ntpIntervalId = null;

        if (isNtpSynced && Math.abs(ntpTimeOffset) > 1000) {
            ntpIntervalId = setInterval(updateNtpCountdown, 1000);
        }

        countdownIntervals.set(rowKey, {
            local: localIntervalId,
            ntp: ntpIntervalId
        });

        console.log(`运单 ${rowKey} 开始双重倒计时 - 本地时间差值: 0ms, NTP时间差值: ${ntpTimeOffset}ms`);
    }

    // 检查并移除自动抢单按钮
    function checkAndRemoveAutoGrabButton(rowKey, grabTimeCell) {
        // 只有两个倒计时都结束了才移除按钮
        const intervals = countdownIntervals.get(rowKey);
        if (intervals && !intervals.local && !intervals.ntp) {
            countdownIntervals.delete(rowKey);

            // 时间到了,移除未使用的自动抢单按钮
            if (!autoGrabTasks.has(rowKey)) {
                const row = grabTimeCell.closest('tr');
                if (row) {
                    const autoBtn = row.querySelector('.auto-grab-btn');
                    if (autoBtn) {
                        autoBtn.remove();
                        console.log(`运单 ${rowKey} 双重倒计时结束,移除自动抢单按钮`);
                    }
                }
            }
        }
    }

    // 添加自动抢单按钮
    function addAutoGrabButton(row, rowKey) {
        const operationCell = row.querySelector('.ant-table-cell-fix-right:not(.ant-table-cell-scrollbar)');
        if (!operationCell) return;

        // 检查是否已经添加过自动抢单按钮
        if (operationCell.querySelector('.auto-grab-btn')) return;

        // 获取可抢单时间,验证这是一个有效的运单行
        const cells = row.querySelectorAll('td');
        if (cells.length < 6) return;

        // 找到"可抢单时间"列
        let grabTimeCell = null;
        cells.forEach((cell, index) => {
            const headerCells = document.querySelectorAll('.ant-table-header thead th');
            if (headerCells[index] && headerCells[index].textContent.includes('可抢单时间')) {
                grabTimeCell = cell;
            }
        });

        if (!grabTimeCell) return;

        const grabTimeText = grabTimeCell.textContent.trim();
        // 从时间字符串中提取第一行作为原始时间
        let originalTime = grabTimeText;
        if (grabTimeText.includes('\n')) {
            originalTime = grabTimeText.split('\n')[0].trim();
        }
        const grabTime = parseTimeString(originalTime);

        if (!grabTime) return; // 时间格式错误,不添加按钮

        // 检查是否已到抢单时间(使用本地时间和NTP时间中较早的一个)
        const localTime = getLocalTime();
        const ntpTime = isNtpSynced ? getNtpTime() : localTime;

        const localTimeDiff = grabTime.getTime() - localTime.getTime();
        const ntpTimeDiff = grabTime.getTime() - ntpTime.getTime();

        // 使用较小的时间差(即较早到达的时间)
        const minTimeDiff = Math.min(localTimeDiff, ntpTimeDiff);

        // 只有时间未到时才显示自动抢单按钮
        if (minTimeDiff <= 0) {
            console.log(`运单 ${rowKey} 时间已到,不显示自动抢单按钮 (本地: ${Math.floor(localTimeDiff / 1000)}s, NTP: ${Math.floor(ntpTimeDiff / 1000)}s)`);
            return;
        }

        console.log(`运单 ${rowKey} 时间检查 - 本地时间差: ${Math.floor(localTimeDiff / 1000)}s, NTP时间差: ${Math.floor(ntpTimeDiff / 1000)}s`);


        // 创建自动抢单按钮
        const autoGrabBtn = document.createElement('button');
        autoGrabBtn.type = 'button';
        autoGrabBtn.className = 'ant-btn ant-btn-primary auto-grab-btn';
        autoGrabBtn.style.cssText = 'margin-left: 5px; background-color: #1890ff; border-color: #1890ff;';
        autoGrabBtn.innerHTML = '<span>自动抢单</span>';

        // 点击事件
        autoGrabBtn.addEventListener('click', function () {
            handleAutoGrab(rowKey, autoGrabBtn, row);
        });

        // 将按钮添加到操作列中
        const operationDiv = operationCell.querySelector('div') || operationCell;
        operationDiv.appendChild(autoGrabBtn);
    }

    // 处理自动抢单逻辑
    function handleAutoGrab(rowKey, autoGrabBtn, row) {
        // 如果已经在自动抢单状态,取消
        if (autoGrabTasks.has(rowKey)) {
            cancelAutoGrab(rowKey, autoGrabBtn);
            return;
        }

        // 获取可抢单时间
        const cells = row.querySelectorAll('td');
        let grabTimeCell = null;
        cells.forEach((cell, index) => {
            const headerCells = document.querySelectorAll('.ant-table-header thead th');
            if (headerCells[index] && headerCells[index].textContent.includes('可抢单时间')) {
                grabTimeCell = cell;
            }
        });

        if (!grabTimeCell) {
            alert('无法找到可抢单时间列');
            return;
        }

        const grabTimeText = grabTimeCell.textContent.trim();
        // 从时间字符串中提取第一行作为原始时间
        let originalTime = grabTimeText;
        if (grabTimeText.includes('\n')) {
            originalTime = grabTimeText.split('\n')[0].trim();
        }
        const grabTime = parseTimeString(originalTime);

        if (!grabTime) {
            alert('获取可抢单时间失败,请检查时间格式');
            return;
        }

        // 计算本地时间和NTP时间的延迟
        const localTime = getLocalTime();
        const ntpTime = isNtpSynced ? getNtpTime() : localTime;

        const localDelay = grabTime.getTime() - localTime.getTime();
        const ntpDelay = grabTime.getTime() - ntpTime.getTime();

        // 如果任何一个时间已到,立即执行抢单
        if (localDelay <= 0 || ntpDelay <= 0) {
            console.log(`运单 ${rowKey} 时间已到,立即执行API抢单 (本地延迟: ${Math.floor(localDelay / 1000)}s, NTP延迟: ${Math.floor(ntpDelay / 1000)}s)`);
            grabOrderByApi(parseInt(rowKey)).then(success => {
                if (success) {
                    console.log(`运单 ${rowKey} API抢单成功`);
                } else {
                    console.warn(`运单 ${rowKey} API抢单失败`);
                }
            });
            return;
        }

        console.log(`运单 ${rowKey} 创建双重自动抢单任务 - 本地延迟: ${Math.floor(localDelay / 1000)}s, NTP延迟: ${Math.floor(ntpDelay / 1000)}s`);

        // 创建抢单执行函数
        const executeGrab = async (timeType) => {
            try {
                console.log(`运单 ${rowKey} ${timeType}定时器触发,执行API抢单`);

                // 检查是否已经被其他定时器执行过
                if (!autoGrabTasks.has(rowKey)) {
                    console.log(`运单 ${rowKey} 已被其他定时器处理,跳过执行`);
                    return;
                }

                const success = await grabOrderByApi(parseInt(rowKey));

                if (success) {
                    console.log(`运单 ${rowKey} ${timeType}自动API抢单成功`);
                } else {
                    console.warn(`运单 ${rowKey} ${timeType}自动API抢单失败`);
                }
            } catch (e) {
                console.error(`运单 ${rowKey} ${timeType}自动抢单异常:`, e);
            } finally {
                // 清理所有相关定时器
                const tasks = autoGrabTasks.get(rowKey);
                if (tasks) {
                    if (tasks.local) {
                        clearTimeout(tasks.local);
                        console.log(`清理运单 ${rowKey} 本地定时器`);
                    }
                    if (tasks.ntp) {
                        clearTimeout(tasks.ntp);
                        console.log(`清理运单 ${rowKey} NTP定时器`);
                    }
                }
                autoGrabTasks.delete(rowKey);
                resetAutoGrabButton(autoGrabBtn);
                updateStatusIndicator();
            }
        };

        // 设置双重自动抢单任务
        const localTimeoutId = setTimeout(() => executeGrab('本地时间'), localDelay);
        let ntpTimeoutId = null;

        // 只有在NTP同步且时间差异显著时才创建NTP定时器
        if (isNtpSynced && Math.abs(ntpDelay - localDelay) > 1000) {
            ntpTimeoutId = setTimeout(() => executeGrab('NTP时间'), ntpDelay);
        }

        // 保存双重任务
        autoGrabTasks.set(rowKey, {
            local: localTimeoutId,
            ntp: ntpTimeoutId
        });
        updateStatusIndicator();

        // 更新按钮状态(使用较小的延迟)
        const minDelay = Math.min(localDelay, ntpDelay);
        updateAutoGrabButton(autoGrabBtn, Math.floor(minDelay / 1000));

        // 淡化倒计时显示(表示正在自动抢单)
        const autoGrabTimeCell = row.querySelectorAll('td').find((_, index) => {
            const headerCells = document.querySelectorAll('.ant-table-header thead th');
            return headerCells[index] && headerCells[index].textContent.includes('可抢单时间');
        });

        if (autoGrabTimeCell) {
            const countdownDisplay = autoGrabTimeCell.querySelector('.countdown-display');
            if (countdownDisplay) {
                countdownDisplay.style.opacity = '0.5';
                countdownDisplay.textContent = '自动抢单中...';
            }
        }
    }

    // 更新自动抢单按钮显示
    function updateAutoGrabButton(button, secondsLeft) {
        const updateDisplay = () => {
            if (secondsLeft <= 0) {
                button.innerHTML = '<span>执行中...</span>';
                button.style.backgroundColor = '#52c41a';
                return;
            }

            button.innerHTML = `<span>等待抢单: ${formatCountdown(secondsLeft)}</span>`;
            button.style.backgroundColor = '#faad14';
            button.style.borderColor = '#faad14';
            secondsLeft--;

            if (secondsLeft >= 0) {
                setTimeout(updateDisplay, 1000);
            }
        };

        updateDisplay();
    }

    // 取消自动抢单(支持双重任务)
    function cancelAutoGrab(rowKey, button) {
        if (autoGrabTasks.has(rowKey)) {
            const tasks = autoGrabTasks.get(rowKey);

            // 支持旧格式和新格式
            if (typeof tasks === 'number') {
                // 旧格式:单个定时器ID
                clearTimeout(tasks);
                console.log(`取消运单 ${rowKey} 的自动抢单任务`);
            } else if (tasks && typeof tasks === 'object') {
                // 新格式:双重定时器对象
                if (tasks.local) {
                    clearTimeout(tasks.local);
                    console.log(`取消运单 ${rowKey} 的本地时间抢单任务`);
                }
                if (tasks.ntp) {
                    clearTimeout(tasks.ntp);
                    console.log(`取消运单 ${rowKey} 的NTP时间抢单任务`);
                }
            }

            autoGrabTasks.delete(rowKey);
            updateStatusIndicator();
        }
        resetAutoGrabButton(button);
    }

    // 重置自动抢单按钮
    function resetAutoGrabButton(button) {
        button.innerHTML = '<span>自动抢单</span>';
        button.style.backgroundColor = '#1890ff';
        button.style.borderColor = '#1890ff';
    }

    // 处理所有行的调试点击功能
    function processDebugClickHandlers() {
        const tableBody = document.querySelector('.ant-table-body tbody');
        if (!tableBody) return;

        const rows = tableBody.querySelectorAll('tr[data-row-key]');
        rows.forEach((row) => {
            const rowKey = row.getAttribute('data-row-key');
            if (rowKey) {
                addDebugClickHandler(row, rowKey);
            }
        });
    }

    // 添加调试点击功能
    function addDebugClickHandler(row, rowKey) {
        // 找到序号列(第2列,索引1)
        const sequenceCell = row.querySelector('td.ant-table-cell-fix-left:not(.ant-table-selection-column)');

        if (sequenceCell && !sequenceCell.hasAttribute('data-debug-added')) {
            // 标记已添加,避免重复绑定
            sequenceCell.setAttribute('data-debug-added', 'true');

            // 添加点击样式提示
            sequenceCell.style.cursor = 'pointer';
            sequenceCell.style.transition = 'background-color 0.2s';
            sequenceCell.title = '点击查看运单详细信息';

            // 添加鼠标悬停效果
            sequenceCell.addEventListener('mouseenter', function () {
                this.style.backgroundColor = '#f0f0f0';
            });

            sequenceCell.addEventListener('mouseleave', function () {
                this.style.backgroundColor = '';
            });

            // 添加点击事件
            sequenceCell.addEventListener('click', function (e) {
                e.stopPropagation(); // 防止事件冒泡

                const orderId = parseInt(rowKey);
                const orderInfo = orderDataMap.get(orderId);

                console.log('='.repeat(60));
                console.log(`🔍 运单调试信息 - 序号: ${this.textContent.trim()}`);
                console.log('='.repeat(60));

                if (orderInfo) {
                    console.log('📋 运单基本信息:');
                    console.log(`   ID: ${orderInfo.id}`);
                    console.log(`   名称: ${orderInfo.name}`);
                    console.log(`   编号: ${orderInfo.code}`);
                    console.log(`   目的地: ${orderInfo.destinationName}`);
                    console.log(`   备注: ${orderInfo.note}`);
                    if (orderInfo.planAllocateTime) {
                        const allocateTime = new Date(orderInfo.planAllocateTime * 1000);
                        const now = new Date();
                        const timeDiff = allocateTime.getTime() - now.getTime();
                        const secondsLeft = Math.floor(timeDiff / 1000);

                        console.log(`   可抢单时间: ${allocateTime.toLocaleString()}`);
                        console.log(`   距离抢单时间: ${secondsLeft > 0 ? secondsLeft + '秒' : '已到时间'}`);
                    }

                    console.log('🚚 Carrier信息:');
                    console.log(`   ID: ${orderInfo.carrier.id}`);
                    console.log(`   名称: ${orderInfo.carrier.name}`);
                    console.log(`   编号: ${orderInfo.carrier.code}`);
                    console.log(`   公司拥有: ${orderInfo.carrier.corporationOwned}`);

                    console.log('🎯 抢单状态:');
                    const hasAutoTask = autoGrabTasks.has(rowKey);
                    const hasCountdown = countdownIntervals.has(rowKey);
                    console.log(`   自动抢单任务: ${hasAutoTask ? '已设置' : '未设置'}`);
                    console.log(`   倒计时任务: ${hasCountdown ? '运行中' : '未运行'}`);

                    // 打印完整的orderInfo对象
                    console.log('📄 完整运单数据:');
                    console.log(JSON.stringify(orderInfo, null, 2));

                } else {
                    console.log('❌ 未找到运单数据');
                    console.log(`   运单ID: ${orderId}`);
                    console.log(`   数据映射表大小: ${orderDataMap.size}`);
                    console.log('   可用运单ID列表:', Array.from(orderDataMap.keys()));
                }

                console.log('='.repeat(60));

                // 在页面上也显示一个简单的提示
                const toast = document.createElement('div');
                toast.style.cssText = `
                    position: fixed;
                    top: 20px;
                    right: 20px;
                    background: #1890ff;
                    color: white;
                    padding: 12px 20px;
                    border-radius: 6px;
                    z-index: 10000;
                    font-size: 14px;
                    box-shadow: 0 2px 8px rgba(0,0,0,0.15);
                `;
                toast.textContent = `运单 ${orderInfo ? orderInfo.code : orderId} 信息已输出到控制台`;
                document.body.appendChild(toast);

                setTimeout(() => {
                    if (toast.parentNode) {
                        toast.parentNode.removeChild(toast);
                    }
                }, 3000);
            });
        }
    }

    // 创建自动抢单状态指示器
    function createStatusIndicator() {
        // 查找标签栏容器
        const tabContainer = document.querySelector('.ant-radio-group');
        if (!tabContainer) {
            console.warn('未找到标签栏容器,无法添加状态指示器');
            return;
        }

        // 检查是否已经添加过
        if (statusIndicator && statusIndicator.parentNode) {
            return;
        }

        // 创建状态指示器
        statusIndicator = document.createElement('div');
        statusIndicator.className = 'auto-grab-status-indicator';
        statusIndicator.style.cssText = `
            display: inline-flex;
            align-items: center;
            margin-left: 20px;
            padding: 4px 12px;
            background: #f0f0f0;
            border: 1px solid #d9d9d9;
            border-radius: 6px;
            cursor: pointer;
            font-size: 12px;
            color: #666;
            transition: all 0.2s;
            min-width: 80px;
            justify-content: center;
        `;

        // 初始内容
        updateStatusIndicator();

        // 添加点击事件
        statusIndicator.addEventListener('click', showAutoGrabModal);

        // 添加悬停效果
        statusIndicator.addEventListener('mouseenter', function () {
            this.style.backgroundColor = '#e6f7ff';
            this.style.borderColor = '#91d5ff';
            this.style.color = '#1890ff';
        });

        statusIndicator.addEventListener('mouseleave', function () {
            const count = autoGrabTasks.size;
            if (count > 0) {
                this.style.backgroundColor = '#fff2f0';
                this.style.borderColor = '#ffccc7';
                this.style.color = '#f5222d';
            } else {
                this.style.backgroundColor = '#f0f0f0';
                this.style.borderColor = '#d9d9d9';
                this.style.color = '#666';
            }
        });

        // 添加到标签栏
        tabContainer.parentNode.style.display = 'flex';
        tabContainer.parentNode.style.alignItems = 'center';
        tabContainer.parentNode.appendChild(statusIndicator);

        console.log('自动抢单状态指示器已添加');
    }

    // 更新状态指示器显示
    function updateStatusIndicator() {
        if (!statusIndicator) return;

        const count = autoGrabTasks.size;

        if (count === 0) {
            statusIndicator.innerHTML = `
                <span style="margin-right: 4px;">⚪</span>
                <span>无自动抢单</span>
            `;
            statusIndicator.style.backgroundColor = '#f0f0f0';
            statusIndicator.style.borderColor = '#d9d9d9';
            statusIndicator.style.color = '#666';
            statusIndicator.title = '当前没有运单在自动抢单';
        } else {
            statusIndicator.innerHTML = `
                <span style="margin-right: 4px;">🔄</span>
                <span>自动抢单: ${count}</span>
            `;
            statusIndicator.style.backgroundColor = '#fff2f0';
            statusIndicator.style.borderColor = '#ffccc7';
            statusIndicator.style.color = '#f5222d';
            statusIndicator.title = `当前有 ${count} 个运单正在自动抢单,点击查看详情`;
        }
    }

    // 显示自动抢单详情弹窗
    function showAutoGrabModal() {
        // 如果弹窗已存在则先移除
        const existingModal = document.getElementById('auto-grab-modal');
        if (existingModal) {
            existingModal.remove();
        }

        // 创建遮罩层
        const overlay = document.createElement('div');
        overlay.id = 'auto-grab-modal';
        overlay.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0, 0, 0, 0.45);
            z-index: 9999;
            display: flex;
            justify-content: center;
            align-items: flex-start;
            padding-top: 100px;
        `;

        // 创建弹窗主体
        const modal = document.createElement('div');
        modal.style.cssText = `
            background: white;
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            max-width: 600px;
            width: 90%;
            max-height: 70vh;
            overflow: hidden;
            display: flex;
            flex-direction: column;
        `;

        // 创建标题栏
        const header = document.createElement('div');
        header.style.cssText = `
            padding: 16px 24px;
            border-bottom: 1px solid #f0f0f0;
            display: flex;
            justify-content: space-between;
            align-items: center;
            background: #fafafa;
        `;

        const title = document.createElement('h3');
        title.style.cssText = `
            margin: 0;
            font-size: 16px;
            font-weight: 600;
            color: #262626;
        `;
        title.textContent = `正在自动抢单的运单 (${autoGrabTasks.size})`;

        const closeBtn = document.createElement('button');
        closeBtn.style.cssText = `
            background: none;
            border: none;
            font-size: 18px;
            cursor: pointer;
            padding: 4px;
            color: #999;
            transition: color 0.2s;
        `;
        closeBtn.innerHTML = '✕';
        closeBtn.addEventListener('click', () => overlay.remove());
        closeBtn.addEventListener('mouseenter', () => closeBtn.style.color = '#f5222d');
        closeBtn.addEventListener('mouseleave', () => closeBtn.style.color = '#999');

        header.appendChild(title);
        header.appendChild(closeBtn);

        // 创建内容区域
        const content = document.createElement('div');
        content.style.cssText = `
            padding: 0;
            overflow-y: auto;
            flex: 1;
        `;

        if (autoGrabTasks.size === 0) {
            content.innerHTML = `
                <div style="padding: 40px; text-align: center; color: #999;">
                    <div style="font-size: 48px; margin-bottom: 16px;">⚪</div>
                    <div style="font-size: 16px;">当前没有运单在自动抢单</div>
                </div>
            `;
        } else {
            // 创建运单列表
            const list = document.createElement('div');
            list.style.cssText = 'padding: 0;';

            autoGrabTasks.forEach((_, rowKey) => {
                const orderInfo = orderDataMap.get(parseInt(rowKey));
                if (!orderInfo) return;

                const item = document.createElement('div');
                item.style.cssText = `
                    padding: 16px 24px;
                    border-bottom: 1px solid #f0f0f0;
                    display: flex;
                    justify-content: space-between;
                    align-items: center;
                    transition: background-color 0.2s;
                `;
                item.addEventListener('mouseenter', () => item.style.backgroundColor = '#f5f5f5');
                item.addEventListener('mouseleave', () => item.style.backgroundColor = 'transparent');

                const leftInfo = document.createElement('div');
                leftInfo.style.cssText = 'flex: 1;';

                // 计算剩余时间
                const now = new Date().getTime();
                let remainingText = '';
                if (orderInfo.planAllocateTime) {
                    const targetTime = new Date(orderInfo.planAllocateTime).getTime();
                    const remaining = targetTime - now;
                    if (remaining > 0) {
                        const minutes = Math.floor(remaining / (1000 * 60));
                        const seconds = Math.floor((remaining % (1000 * 60)) / 1000);
                        remainingText = `${minutes}分${seconds}秒后执行`;
                    } else {
                        remainingText = '即将执行';
                    }
                }

                leftInfo.innerHTML = `
                    <div style="font-weight: 500; font-size: 14px; color: #262626; margin-bottom: 4px;">
                        ${orderInfo.code || rowKey}
                    </div>
                    <div style="font-size: 12px; color: #666; margin-bottom: 2px;">
                        目的地: ${orderInfo.destination || '未知'}
                    </div>
                    <div style="font-size: 12px; color: #1890ff;">
                        ${remainingText}
                    </div>
                `;

                const rightBtn = document.createElement('button');
                rightBtn.style.cssText = `
                    background: #fff2f0;
                    border: 1px solid #ffccc7;
                    border-radius: 4px;
                    padding: 4px 8px;
                    font-size: 12px;
                    color: #f5222d;
                    cursor: pointer;
                    transition: all 0.2s;
                `;
                rightBtn.textContent = '取消';
                rightBtn.addEventListener('click', () => {
                    // 取消自动抢单
                    if (autoGrabTasks.has(rowKey)) {
                        clearTimeout(autoGrabTasks.get(rowKey));
                        autoGrabTasks.delete(rowKey);
                        updateStatusIndicator();
                        console.log(`已取消运单 ${rowKey} 的自动抢单`);

                        // 更新按钮状态
                        const autoGrabBtn = document.querySelector(`tr[data-row-key="${rowKey}"] .auto-grab-btn`);
                        if (autoGrabBtn) {
                            autoGrabBtn.textContent = '自动抢单';
                            autoGrabBtn.style.backgroundColor = '#fff';
                            autoGrabBtn.style.borderColor = '#d9d9d9';
                            autoGrabBtn.style.color = '#666';
                        }

                        // 刷新弹窗内容
                        showAutoGrabModal();
                    }
                });
                rightBtn.addEventListener('mouseenter', () => {
                    rightBtn.style.backgroundColor = '#f5222d';
                    rightBtn.style.color = 'white';
                });
                rightBtn.addEventListener('mouseleave', () => {
                    rightBtn.style.backgroundColor = '#fff2f0';
                    rightBtn.style.color = '#f5222d';
                });

                item.appendChild(leftInfo);
                item.appendChild(rightBtn);
                list.appendChild(item);
            });

            content.appendChild(list);
        }

        // 点击遮罩层关闭弹窗
        overlay.addEventListener('click', (e) => {
            if (e.target === overlay) {
                overlay.remove();
            }
        });

        // 组装弹窗
        modal.appendChild(header);
        modal.appendChild(content);
        overlay.appendChild(modal);
        document.body.appendChild(overlay);
    }

    // 处理抢单按钮
    function setupGrabButtons() {
        const buttons = document.querySelectorAll('.ant-btn-dangerous');
        buttons.forEach(button => {
            if (!button.hasAttribute('data-grab-handler')) {
                button.setAttribute('data-grab-handler', 'true');

                // 根据设置修改按钮文本
                button.innerHTML = `<span>${settings.skipGrabConfirm ? '直接抢单' : '抢单'}</span>`;

                // 添加点击事件处理
                button.addEventListener('click', function (event) {
                    if (!settings.skipGrabConfirm) return; // 如果未开启跳过确认,不做任何处理

                    event.stopPropagation(); // 阻止事件冒泡
                    event.preventDefault(); // 阻止默认行为

                    // 获取运单行
                    const row = button.closest('tr[data-row-key]');
                    if (!row) return;

                    const rowKey = row.getAttribute('data-row-key');
                    if (!rowKey) return;

                    // 调用API直接抢单
                    console.log(`直接抢单:运单 ${rowKey}`);
                    grabOrderByApi(parseInt(rowKey)).then(success => {
                        if (success) {
                            console.log(`运单 ${rowKey} API抢单成功`);
                            // 可以在这里添加成功提示
                        } else {
                            console.warn(`运单 ${rowKey} API抢单失败`);
                            // 可以在这里添加失败提示
                        }
                    });
                });
            }
        });
    }

    // 观察DOM变化
    function setupObserver() {
        const observer = new MutationObserver(function (mutations) {
            let shouldUpdate = false;
            let shouldUpdateGrabButtons = false;

            mutations.forEach(function (mutation) {
                if (mutation.type === 'childList') {
                    // 检查是否有表格相关的变化
                    mutation.addedNodes.forEach(function (node) {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            if (node.matches && (
                                node.matches('tr[data-row-key]') ||
                                node.querySelector && node.querySelector('tr[data-row-key]')
                            )) {
                                shouldUpdate = true;
                            }

                            // 检查是否有抢单按钮相关的变化
                            if (node.matches && (
                                node.matches('.ant-btn-dangerous') ||
                                node.querySelector && node.querySelector('.ant-btn-dangerous')
                            )) {
                                shouldUpdateGrabButtons = true;
                            }
                        }
                    });
                }
            });

            if (shouldUpdate && isOnGrabOrderTab()) {
                setTimeout(() => {
                    processTableRows();
                    // 确保操作列宽度足够
                    ensureOperationColumnWidth();
                    // 处理调试点击功能
                    processDebugClickHandlers();
                }, 100);
            }

            if (shouldUpdateGrabButtons && isOnGrabOrderTab()) {
                setTimeout(() => {
                    setupGrabButtons();
                }, 100);
            }
        });

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

    // 监听页面标签切换
    function setupTabListener() {
        document.addEventListener('click', function (e) {
            const target = e.target;
            if (target.matches('.ant-radio-button-input') ||
                target.closest('.ant-radio-button-wrapper')) {

                setTimeout(() => {
                    console.log('检测到标签切换,当前标签:', isOnGrabOrderTab() ? '抢单' : '其他');
                    if (isOnGrabOrderTab()) {
                        processTableRows();
                        ensureOperationColumnWidth();
                        setupGrabButtons(); // 处理抢单按钮
                        processDebugClickHandlers(); // 处理调试点击功能
                    } else {
                        // 切换到其他标签时清理所有任务
                        console.log('切换离开抢单标签,清理所有任务');

                        // 清理倒计时任务(支持双重倒计时)
                        countdownIntervals.forEach((intervals, rowKey) => {
                            if (typeof intervals === 'number') {
                                // 旧格式:单个interval ID
                                clearInterval(intervals);
                            } else if (intervals && typeof intervals === 'object') {
                                // 新格式:双重interval对象
                                if (intervals.local) clearInterval(intervals.local);
                                if (intervals.ntp) clearInterval(intervals.ntp);
                            }
                            console.log(`清理运单 ${rowKey} 的倒计时任务`);
                        });
                        countdownIntervals.clear();

                        // 清理自动抢单任务(支持双重任务)
                        autoGrabTasks.forEach((tasks, rowKey) => {
                            if (typeof tasks === 'number') {
                                // 旧格式:单个timeout ID
                                clearTimeout(tasks);
                            } else if (tasks && typeof tasks === 'object') {
                                // 新格式:双重timeout对象
                                if (tasks.local) clearTimeout(tasks.local);
                                if (tasks.ntp) clearTimeout(tasks.ntp);
                            }
                            console.log(`清理运单 ${rowKey} 的自动抢单任务`);
                        });
                        autoGrabTasks.clear();
                        updateStatusIndicator();
                    }
                }, 500);
            }
        });
    }

    // 初始化脚本
    function init() {
        console.log('运单自动抢单助手已加载');

        // 加载设置
        loadSettings();

        // 等待页面完全加载
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function () {
                setTimeout(() => justDoIt(), 1000);
            });
        } else {
            setTimeout(() => justDoIt(), 1000);
        }
    }

    function justDoIt() {
        createSettingsButton();
        // 直接启动脚本功能
        if (settings.showCountdown || settings.enableAutoGrab || settings.enableDestinationMatch) {
            start();
        }
        // 初始化自动刷新功能
        setupAutoRefresh();
    }

    function start() {
        if (settings.showCountdown || settings.enableAutoGrab) {
            // 启动NTP时间同步
            syncNtpTime();
            createStatusIndicator(); // 创建状态指示器
        }

        setupApiInterceptor(); // 设置API拦截器
        setupObserver();
        setupTabListener();

        // 初始化目的地匹配面板
        if (settings.enableDestinationMatch && destinationList.length > 0) {
            createMatchInfoPanel();
        }

        // 如果当前就在抢单页面,立即处理
        if (isOnGrabOrderTab()) {
            processTableRows();
            ensureOperationColumnWidth();
            setupGrabButtons(); // 处理抢单按钮
            processDebugClickHandlers(); // 处理调试点击功能
        }

        console.log('运单自动抢单助手启动完成');
        console.log(`时间同步状态: ${isNtpSynced ? 'NTP已同步' : '使用本地时间'}`);
    }

    // 页面卸载时清理资源
    window.addEventListener('beforeunload', function () {
        // 清理倒计时任务
        countdownIntervals.forEach((intervals) => {
            if (typeof intervals === 'number') {
                clearInterval(intervals);
            } else if (intervals && typeof intervals === 'object') {
                if (intervals.local) clearInterval(intervals.local);
                if (intervals.ntp) clearInterval(intervals.ntp);
            }
        });

        // 清理自动抢单任务
        autoGrabTasks.forEach((tasks) => {
            if (typeof tasks === 'number') {
                clearTimeout(tasks);
            } else if (tasks && typeof tasks === 'object') {
                if (tasks.local) clearTimeout(tasks.local);
                if (tasks.ntp) clearTimeout(tasks.ntp);
            }
        });
    });

    // 监听API请求,拦截查询接口获取运单数据
    function setupApiInterceptor() {
        const originalFetch = window.fetch;
        const originalXHR = XMLHttpRequest.prototype.open;

        // 拦截fetch请求
        window.fetch = function (url) {
            const promise = originalFetch.apply(this, arguments);
            console.log('拦截到fetch请求:', url);
            // 检查是否是查询接口
            if (url && url.includes('/api/data_query/query')) {
                promise.then(response => {
                    console.log('拦截到查询接口请求:', url);
                    if (response.ok) {
                        // 克隆响应以避免消费原始流
                        return response.clone().json().then(data => {
                            handleQueryResponse(data);
                        }).catch(err => {
                            console.error('解析查询接口响应失败:', err);
                        });
                    }
                }).catch(err => {
                    console.error('查询接口请求失败:', err);
                });
            }

            return promise;
        };

        // 拦截XMLHttpRequest请求
        XMLHttpRequest.prototype.open = function (_, url) {
            console.log('拦截到XHR请求:', url);
            if (url && url.includes('/api/data_query/query')) {
                const xhr = this;

                xhr.addEventListener('load', function () {
                    try {
                        if (xhr.status === 200 && xhr.responseText) {
                            const data = JSON.parse(xhr.responseText);
                            handleQueryResponse(data);
                        }
                    } catch (err) {
                        console.error('解析XHR查询接口响应失败:', err);
                    }
                });
            }

            return originalXHR.apply(this, arguments);
        };

        console.log('API拦截器已设置');
    }

    // 处理查询接口响应数据
    function handleQueryResponse(data) {
        if (!data || !data.data || !Array.isArray(data.data.results)) {
            console.warn('查询接口响应数据格式不正确:', data);
            return;
        }

        console.log(`收到查询接口响应,运单数量: ${data.data.results.length}`);
        orderDataMap.clear();

        // 从页面获取当前用户的carrier信息
        let defaultCarrier = {
            corporationOwned: false,
            code: "000207",
            name: "鑫利物流30",
            id: 76
        };

        // 尝试从页面元素中获取carrier信息
        try {
            const userInfoElement = document.querySelector('[data-carrier-info]');
            if (userInfoElement) {
                const carrierInfo = JSON.parse(userInfoElement.getAttribute('data-carrier-info'));
                if (carrierInfo) {
                    defaultCarrier = carrierInfo;
                }
            }
        } catch (e) {
            console.warn('无法从页面获取carrier信息,使用默认值');
        }

        // 更新运单数据映射
        data.data.results.forEach(order => {
            if (order.id && order.code) {
                // 解析备注信息
                let note = order.customer.site.extJSON?.match(/\"xqbz\":\"([^\"]*)\"/)?.[1]
                    || order.extJSON?.match(/\"xqbz\":\"([^\"]*)\"/)?.[1] || '';
                const orderInfo = {
                    id: order.id,
                    name: order.name || '', // 运单名称
                    code: order.code, // 运单编号
                    planAllocateTime: order.planAllocateTime, // 可抢单时间
                    destinationName: order.destinationPoint.formatName || '', // 目的地名称
                    note: note, // 备注信息,从extJSON中的xqbz字段解析
                    // 使用默认carrier信息或从order中获取
                    carrier: order.carrier || defaultCarrier
                };

                orderDataMap.set(order.id, orderInfo);
                console.log(`更新运单数据: ID=${orderInfo.id}, Code=${orderInfo.code}, 目的地=${orderInfo.destinationName},
                     可抢单时间=${orderInfo.planAllocateTime}, 备注=${orderInfo.note}`);
            }
        });

        console.log(`运单数据映射已更新,当前存储 ${orderDataMap.size} 个运单`);

        // 处理目的地匹配逻辑
        processDestinationMatching();

        // 数据更新后立即处理调试点击功能
        if (isOnGrabOrderTab()) {
            processDebugClickHandlers();
        }
    }

    // 处理目的地匹配逻辑
    function processDestinationMatching() {
        // 如果未启用目的地匹配或没有配置目的地,直接返回
        if (!settings.enableDestinationMatch || destinationList.length === 0) {
            matchedOrders.clear();
            updateMatchInfoPanel();
            return;
        }

        console.log('开始处理目的地匹配,配置的目的地:', destinationList);

        // 清空之前匹配的订单
        matchedOrders.clear();

        // 遍历所有订单进行匹配
        orderDataMap.forEach(order => {
            if (!order.id || !order.destinationName) {
                return;
            }

            const destinationName = order.destinationName.trim();

            // 检查是否匹配配置的目的地(支持模糊匹配)
            const matchedDestination = destinationList.find(configDestination =>
                destinationName.includes(configDestination) ||
                configDestination.includes(destinationName)
            );

            if (matchedDestination) {
                // 判断备注是否符合条件
                let shouldGrab = false;
                const orderNote = order.note.trim();
                
                if (orderNote === '') {
                    // 备注为空,直接抢单
                    shouldGrab = true;
                    console.log(`发现匹配订单: ${order.code}, 目的地: ${destinationName}, 匹配配置: ${matchedDestination}, 备注为空,允许抢单`);
                } else {
                    // 备注不为空,检查白名单和黑名单
                    if (noteConfig.mode === 'whitelist' && noteConfig.whitelist.length > 0) {
                        // 白名单模式:检查是否命中白名单
                        const hitWhitelist = noteConfig.whitelist.some(keyword => orderNote.includes(keyword));
                        shouldGrab = hitWhitelist;
                        console.log(`发现匹配订单: ${order.code}, 目的地: ${destinationName}, 匹配配置: ${matchedDestination}, 备注: "${orderNote}", 白名单模式: ${hitWhitelist ? '命中白名单,允许抢单' : '未命中白名单,不抢单'}`);
                    } else if (noteConfig.mode === 'blacklist' && noteConfig.blacklist.length > 0) {
                        // 黑名单模式:检查是否命中黑名单
                        const hitBlacklist = noteConfig.blacklist.some(keyword => orderNote.includes(keyword));
                        shouldGrab = !hitBlacklist;
                        console.log(`发现匹配订单: ${order.code}, 目的地: ${destinationName}, 匹配配置: ${matchedDestination}, 备注: "${orderNote}", 黑名单模式: ${hitBlacklist ? '命中黑名单,不抢单' : '未命中黑名单,允许抢单'}`);
                    } else {
                        // 没有配置备注过滤规则,有备注的情况下不抢单(保持原逻辑)
                        shouldGrab = false;
                        console.log(`发现匹配订单: ${order.code}, 目的地: ${destinationName}, 匹配配置: ${matchedDestination}, 备注: "${orderNote}", 未配置备注过滤规则,不抢单`);
                    }
                }

                if (shouldGrab) {
                    // 创建匹配订单信息
                    const matchedOrderInfo = { ...order };

                    matchedOrders.set(order.id, matchedOrderInfo);

                    // 检查是否到了抢单时间,如果是则立即抢单
                    if (order.planAllocateTime) {
                        const grabTime = new Date(order.planAllocateTime * 1000);
                        const now = new Date();
                        const timeDiff = grabTime.getTime() - now.getTime();

                        if (timeDiff <= 0) {
                            // 时间已到,立即抢单
                            console.log(`匹配订单 ${order.code} 时间已到,立即执行抢单`);
                            executeDestinationMatchGrab(order.id, matchedOrderInfo);
                        } else {
                            // 设置定时抢单
                            console.log(`匹配订单 ${order.code} 设置定时抢单,${Math.floor(timeDiff / 1000)}秒后执行`);
                            setTimeout(() => {
                                executeDestinationMatchGrab(order.id, matchedOrderInfo);
                            }, timeDiff);
                        }
                    } else {
                        executeDestinationMatchGrab(order.id, matchedOrderInfo);
                    }
                }
            }
        });

        console.log(`目的地匹配完成,匹配到 ${matchedOrders.size} 个订单`);

        // 更新浮动面板显示
        updateMatchInfoPanel();
    }

    // 执行目的地匹配抢单
    async function executeDestinationMatchGrab(orderId, orderInfo) {
        // 检查订单是否还在匹配列表中(可能已被手动取消)
        if (!matchedOrders.has(orderId)) {
            console.log(`订单 ${orderId} 不在匹配列表中,跳过抢单`);
            return;
        }

        console.log(`开始执行目的地匹配抢单: ${orderInfo.code}`);

        // 更新状态为抢单中
        updateMatchOrderStatus(orderId, 'grabbing');

        try {
            const success = await grabOrderByApi(orderId);

            if (success) {
                console.log(`目的地匹配抢单成功: ${orderInfo.code}`);
                updateMatchOrderStatus(orderId, 'success');

                // 显示成功提示
                showMatchGrabToast(orderInfo, 'success');

                // 成功后延迟移除(让用户看到成功状态)
                setTimeout(() => {
                    matchedOrders.delete(orderId);
                    updateMatchInfoPanel();
                }, 3000);
            } else {
                console.log(`目的地匹配抢单失败: ${orderInfo.code}`);
                updateMatchOrderStatus(orderId, 'failed');
                showMatchGrabToast(orderInfo, 'failed');

                // 失败后也延迟移除
                setTimeout(() => {
                    matchedOrders.delete(orderId);
                    updateMatchInfoPanel();
                }, 5000);
            }
        } catch (error) {
            console.error(`目的地匹配抢单异常: ${orderInfo.code}`, error);
            updateMatchOrderStatus(orderId, 'failed');
            showMatchGrabToast(orderInfo, 'error');

            setTimeout(() => {
                matchedOrders.delete(orderId);
                updateMatchInfoPanel();
            }, 5000);
        }
    }

    // 显示匹配抢单结果提示
    function showMatchGrabToast(orderInfo, status) {
        const toast = document.createElement('div');
        toast.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            min-width: 280px;
            padding: 12px 16px;
            border-radius: 6px;
            z-index: 10001;
            font-size: 14px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            animation: slideInFromRight 0.3s ease;
        `;

        // 根据状态设置样式和内容
        if (status === 'success') {
            toast.style.background = '#f6ffed';
            toast.style.border = '1px solid #b7eb8f';
            toast.style.color = '#389e0d';
            toast.innerHTML = `
                <div style="font-weight: 500; margin-bottom: 4px;">✅ 匹配抢单成功</div>
                <div style="font-size: 12px; opacity: 0.8;">运单: ${orderInfo.code}</div>
                <div style="font-size: 12px; opacity: 0.8;">目的地: ${orderInfo.destinationName}</div>
            `;
        } else {
            toast.style.background = '#fff2f0';
            toast.style.border = '1px solid #ffccc7';
            toast.style.color = '#cf1322';
            toast.innerHTML = `
                <div style="font-weight: 500; margin-bottom: 4px;">❌ 匹配抢单失败</div>
                <div style="font-size: 12px; opacity: 0.8;">运单: ${orderInfo.code}</div>
                <div style="font-size: 12px; opacity: 0.8;">目的地: ${orderInfo.destinationName}</div>
            `;
        }

        // 添加动画样式
        const style = document.createElement('style');
        style.textContent = `
            @keyframes slideInFromRight {
                from { transform: translateX(100%); opacity: 0; }
                to { transform: translateX(0); opacity: 1; }
            }
        `;
        if (!document.head.querySelector('style[data-match-toast]')) {
            style.setAttribute('data-match-toast', 'true');
            document.head.appendChild(style);
        }

        document.body.appendChild(toast);

        // 自动移除提示
        setTimeout(() => {
            if (toast.parentNode) {
                toast.style.animation = 'slideInFromRight 0.3s ease reverse';
                setTimeout(() => {
                    if (toast.parentNode) {
                        toast.parentNode.removeChild(toast);
                    }
                }, 300);
            }
        }, status === 'success' ? 3000 : 5000);
    }

    // 直接调用抢单API
    async function grabOrderByApi(orderId) {
        const orderInfo = orderDataMap.get(orderId);
        if (!orderInfo) {
            console.error(`运单 ${orderId} 信息不存在,无法抢单`);
            return false;
        }

        const requestBody = {
            id: orderInfo.id,
            name: orderInfo.name,
            code: orderInfo.code,
            version: 4, // 固定值,根据API文档
            carrier: orderInfo.carrier
        };

        console.log(`开始API抢单,运单 ${orderId}:`, requestBody);

        try {
            const response = await fetch('/api/way_bill/dispatch/carrier/grab/order', {
                method: 'POST',
                headers: {
                    'Accept': 'application/json',
                    'Content-Type': 'application/json;charset=UTF-8',
                    'Origin': window.location.origin,
                    'Referer': window.location.origin + '/',
                    'DNT': '1',
                    'Sec-Fetch-Dest': 'empty',
                    'Sec-Fetch-Mode': 'cors',
                    'Sec-Fetch-Site': 'same-origin'
                },
                body: JSON.stringify(requestBody),
                credentials: 'same-origin' // 包含cookies
            });

            if (response.ok) {
                const result = await response.json();
                if (result.status) {
                    console.error(`运单 ${orderId} 抢单失败:`, result);
                    return false;
                } else {
                    console.log(`运单 ${orderId} 抢单成功!`);
                    return true;
                }
            } else {
                console.error(`运单 ${orderId} 抢单请求失败,状态码:`, response.status);
                return false;
            }
        } catch (error) {
            console.error(`运单 ${orderId} 抢单API调用异常:`, error);
            return false;
        }
    }

    console.log('已添加测试函数 window.testSettings(),可在控制台运行测试');

    // 启动脚本
    init();

})();