Greasy Fork

Greasy Fork is available in English.

豆包&即梦AI下载无水印图片视频

实现豆包&即梦生成的图片视频免费无水印下载

当前为 2025-02-24 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         豆包&即梦AI下载无水印图片视频
// @namespace    http://tampermonkey.net/
// @version      3.5.3
// @description  实现豆包&即梦生成的图片视频免费无水印下载
// @author       微信11208596
// @license      UNLICENSED
// @match        https://www.doubao.com/*
// @match        https://jimeng.jianying.com/ai-tool/*
// @grant        GM_download
// @grant        GM_xmlhttpRequest
// ==/UserScript==

(function () {
    'use strict';

    // 添加激活码相关功能
    const ACTIVATION_KEY = 'doubao_activation_status';
    const SECRET_KEY = 'db94xy20240322'; // 使用一个固定的密钥值
    const VALID_DAYS = 30; // 激活码有效期(天)

    // 飞书多维表格配置
    const FEISHU_CONFIG = {
        APP_ID: 'cli_a7317a5d6afd901c',
        APP_SECRET: 'cdGf1f5n5xY0tI6F07xKkcU1iPoFVdPD',
        BASE_ID: 'T1M4bzmLLarNLhs5jcEcwAcRn8Q',    // 多维表格 base ID
        TABLE_ID: 'tbliBckxa87pskV8',              // 数据表 ID
        API_URL: 'https://open.feishu.cn/open-apis',
        TOKEN: null
    };

    // 修改获取访问令牌的函数
    async function getFeishuAccessToken() {
        return new Promise((resolve, reject) => {
            GM_xmlhttpRequest({
                method: 'POST',
                url: 'https://open.feishu.cn/open-apis/auth/v3/tenant_access_token/internal',
                headers: {
                    'Content-Type': 'application/json; charset=utf-8'
                },
                data: JSON.stringify({
                    "app_id": FEISHU_CONFIG.APP_ID,
                    "app_secret": FEISHU_CONFIG.APP_SECRET
                }),
                onload: function(response) {
                    try {
                        const data = JSON.parse(response.responseText);
                        console.log('访问令牌响应:', data);

                        if (data.code === 0 && data.tenant_access_token) {
                            FEISHU_CONFIG.TOKEN = data.tenant_access_token;
                            resolve(data.tenant_access_token);
                        } else {
                            console.error('获取访问令牌失败:', data);
                            reject(new Error(`获取访问令牌失败: ${data.msg || '未知错误'}`));
                        }
                    } catch (e) {
                        console.error('解析响应失败:', e);
                        reject(e);
                    }
                },
                onerror: function(error) {
                    console.error('请求失败:', error);
                    reject(error);
                }
            });
        });
    }

    // 修改生成激活码的函数
    async function generateActivationCode() {
        try {
            if (!FEISHU_CONFIG.TOKEN) {
                await getFeishuAccessToken();
            }

            // 生成随机部分
            const randomPart = Math.random().toString(36).substring(2, 10);
            // 时间戳部分
            const timestampPart = Date.now().toString(36);
            // 校验部分
            const checkPart = generateCheckPart(randomPart + timestampPart);
            // 组合激活码
            const code = `${randomPart}-${timestampPart}-${checkPart}`;

            // 计算过期时间
            const expireTime = new Date();
            expireTime.setDate(expireTime.getDate() + VALID_DAYS);

            // 创建新记录
            const response = await fetch(`${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    fields: {
                        '激活码': code,
                        '状态': '正常',
                        '过期时间': expireTime.toISOString(),
                        '创建时间': new Date().toISOString()
                    }
                })
            });

            const data = await response.json();
            if (data.code === 0) {
                return code;
            } else {
                console.error('创建激活码失败:', data);
                return null;
            }
        } catch (e) {
            console.error('生成激活码出错:', e);
            return null;
        }
    }

    // 生成校验部分
    function generateCheckPart(str) {
        let hash = 0;
        for (let i = 0; i < str.length; i++) {
            const char = str.charCodeAt(i);
            hash = ((hash << 5) - hash) + char;
            hash = hash & hash; // Convert to 32-bit integer
        }
        return Math.abs(hash).toString(36).substring(0, 4);
    }

    // 添加获取字段信息的函数
    async function getTableFields() {
        const token = await getFeishuAccessToken();
        return new Promise((resolve, reject) => {
            const url = `${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/fields`;

            GM_xmlhttpRequest({
                method: 'GET',
                url: url,
                headers: {
                    'Authorization': `Bearer ${token}`,
                    'Content-Type': 'application/json; charset=utf-8'
                },
                onload: function(response) {
                    try {
                        const data = JSON.parse(response.responseText);
                        console.log('字段信息:', data);
                        if (data.code === 0) {
                            resolve(data.data.items);
                        } else {
                            reject(new Error(data.msg));
                        }
                    } catch (e) {
                        reject(e);
                    }
                },
                onerror: reject
            });
        });
    }

    // 修改验证激活码的函数
    async function verifyActivationCode(deviceId, code) {
        try {
            // 获取访问令牌
            const token = await getFeishuAccessToken();
            console.log('获取到的访问令牌:', token);

            return new Promise((resolve, reject) => {
                const url = `${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records/search`;

                // 修改请求数据格式,只查询设备ID
                const requestData = {
                    page_size: 10,
                    field_names: ["设备ID", "状态", "过期时间"],
                    filter: {
                        conjunction: "and",
                        conditions: [
                            {
                                field_name: "设备ID",
                                operator: "is",
                                value: [deviceId]    // 值必须是数组格式
                            }
                        ]
                    }
                };

                console.log('请求数据:', JSON.stringify(requestData));

                GM_xmlhttpRequest({
                    method: 'POST',
                    url: url,
                    headers: {
                        'Authorization': `Bearer ${token}`,
                        'Content-Type': 'application/json; charset=utf-8'
                    },
                    data: JSON.stringify(requestData),
                    onload: function(response) {
                        try {
                            const data = JSON.parse(response.responseText);
                            console.log('验证响应:', data);

                            if (data.code !== 0) {
                                reject(new Error(data.msg || '验证失败'));
                                return;
                            }

                            // 检查记录是否存在
                            if (!data.data?.items || data.data.items.length === 0) {
                                resolve(false);
                                return;
                            }

                            const record = data.data.items[0].fields;

                            // 只检查状态是否正常
                            if (record.状态 !== '正常') {
                                resolve(false);
                                return;
                            }

                            // 验证过期时间
                            const expireTime = new Date(record.过期时间);
                            if (expireTime < new Date()) {
                                resolve(false);
                                return;
                            }

                            // 保存激活信息
                            localStorage.setItem('activation_code', code);
                            localStorage.setItem(ACTIVATION_KEY, 'activated');
                            localStorage.setItem('expire_time', expireTime.toISOString());

                            resolve(true);
                        } catch (e) {
                            console.error('处理响应失败:', e);
                            reject(e);
                        }
                    },
                    onerror: function(error) {
                        console.error('请求失败:', error);
                        reject(error);
                    }
                });
            });
        } catch (e) {
            console.error('验证过程出错:', e);
            return false;
        }
    }

    // 修改更新激活记录的函数
    async function updateActivationRecord(recordId, fields) {
        return new Promise((resolve, reject) => {
            if (!FEISHU_CONFIG.TOKEN) {
                reject(new Error('没有访问令牌'));
                return;
            }

            GM_xmlhttpRequest({
                method: 'PUT',
                url: `${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records/${recordId}`,
                headers: {
                    'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`,
                    'Content-Type': 'application/json'
                },
                data: JSON.stringify({ fields }),
                onload: function(response) {
                    const data = JSON.parse(response.responseText);
                    if (data.code === 0) {
                        resolve(data);
                    } else {
                        reject(new Error('更新记录失败'));
                    }
                },
                onerror: function(error) {
                    reject(error);
                }
            });
        });
    }

    // 修改检查激活状态的函数
    async function checkActivation() {
        const activationStatus = localStorage.getItem(ACTIVATION_KEY);
        const deviceId = localStorage.getItem('deviceId');
        const activationCode = localStorage.getItem('activation_code');
        const recordId = localStorage.getItem('record_id');
        const expireTime = localStorage.getItem('expire_time');

        if (!deviceId || !activationStatus || !activationCode || !recordId || !expireTime) {
            return false;
        }

        // 检查本地过期时间
        if (new Date() > new Date(expireTime)) {
            localStorage.removeItem(ACTIVATION_KEY);
            localStorage.removeItem('activation_code');
            localStorage.removeItem('record_id');
            localStorage.removeItem('expire_time');
            showFloatingTip('激活码已过期,请重新激活');
            return false;
        }

        // 检查飞书表格中的状态
        try {
            if (!FEISHU_CONFIG.TOKEN) {
                await getFeishuAccessToken();
            }

            const response = await fetch(`${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records/${recordId}`, {
                method: 'GET',
                headers: {
                    'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`
                }
            });

            const data = await response.json();
            if (data.code === 0) {
                const record = data.data.record.fields;
                const serverExpireTime = new Date(record.过期时间);
                const now = new Date();

                if (record.状态 === '已禁用' || now > serverExpireTime) {
                    localStorage.removeItem(ACTIVATION_KEY);
                    localStorage.removeItem('activation_code');
                    localStorage.removeItem('record_id');
                    localStorage.removeItem('expire_time');
                    showFloatingTip('激活码已失效,请重新激活');
                    return false;
                }

                // 更新本地过期时间
                localStorage.setItem('expire_time', serverExpireTime.toISOString());
                return true;
            }
        } catch (e) {
            console.error('检查激活状态出错:', e);
            // 如果网络请求失败,暂时使用本地存储的状态
            return activationStatus === 'activated';
        }

        return false;
    }

    // 修改激活对话框样式
    function createActivationDialog() {
        const overlay = document.createElement('div');
        overlay.className = 'download-confirm-overlay';

        const dialog = document.createElement('div');
        dialog.className = 'download-confirm-dialog';

        const deviceId = localStorage.getItem('deviceId') ||
                        Math.random().toString(36).substring(2) + Date.now().toString(36);

        if (!localStorage.getItem('deviceId')) {
            localStorage.setItem('deviceId', deviceId);
        }

        dialog.innerHTML = `
            <h3 style="font-size: 17px; margin-bottom: 4px;">软件激活</h3>
            <p style="color: #999; font-size: 14px; margin: 0 0 20px;">请输入激活码以继续使用</p>
            <div class="input-container" style="margin-bottom: 12px;">
                <label style="color: #333; font-size: 14px; display: block; margin-bottom: 8px;">设备ID</label>
                <input type="text"
                       id="deviceId"
                       value="${deviceId}"
                       readonly
                       style="width: 100%;
                              padding: 12px;
                              border: 1px solid #e5e5e5;
                              border-radius: 8px;
                              font-size: 14px;
                              background: #f5f5f5;">
                <div class="tip" style="font-size: 12px; color: #999; margin-top: 4px;">
                    请复制设备ID并联系微信(11208596)获取激活码
                </div>
            </div>
            <div class="input-container" style="margin-bottom: 20px;">
                <label style="color: #333; font-size: 14px; display: block; margin-bottom: 8px;">激活码</label>
                <input type="text"
                       id="activationCode"
                       placeholder="请输入激活码"
                       style="width: 100%;
                              padding: 12px;
                              border: 1px solid #e5e5e5;
                              border-radius: 8px;
                              font-size: 14px;">
            </div>
            <div class="buttons" style="display: flex; gap: 12px;">
                <button class="cancel-btn"
                        style="flex: 1;
                               padding: 12px;
                               border: none;
                               border-radius: 8px;
                               font-size: 14px;
                               background: #f5f5f5;
                               color: #333;
                               cursor: pointer;">
                    取消
                </button>
                <button class="confirm-btn"
                        style="flex: 1;
                               padding: 12px;
                               border: none;
                               border-radius: 8px;
                               font-size: 14px;
                               background: #007AFF;
                               color: white;
                               cursor: pointer;">
                    激活
                </button>
            </div>
        `;

        document.body.appendChild(overlay);
        document.body.appendChild(dialog);

        // 添加样式
        const style = document.createElement('style');
        style.textContent = `
            .download-confirm-overlay {
                position: fixed;
                top: 0;
                left: 0;
                right: 0;
                bottom: 0;
                background: rgba(0, 0, 0, 0.4);
                backdrop-filter: blur(8px);
                z-index: 9999;
            }

            .download-confirm-dialog {
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background: white;
                padding: 24px;
                border-radius: 12px;
                width: 90%;
                max-width: 360px;
                box-shadow: 0 20px 40px rgba(0, 0, 0, 0.1);
                z-index: 10000;
            }

            .confirm-btn:hover {
                background: #0066DD !important;
            }

            .cancel-btn:hover {
                background: #eee !important;
            }

            .confirm-btn:active {
                transform: scale(0.98);
            }

            .cancel-btn:active {
                transform: scale(0.98);
            }
        `;
        document.head.appendChild(style);

        const confirmBtn = dialog.querySelector('.confirm-btn');
        const cancelBtn = dialog.querySelector('.cancel-btn');
        const activationInput = dialog.querySelector('#activationCode');
        const deviceIdInput = dialog.querySelector('#deviceId');

        // 复制设备ID功能
        deviceIdInput.addEventListener('click', () => {
            deviceIdInput.select();
            document.execCommand('copy');
            showFloatingTip('设备ID已复制到剪贴板');
        });

        function closeDialog() {
            document.body.removeChild(overlay);
            document.body.removeChild(dialog);
        }

        confirmBtn.addEventListener('click', async () => {
            const code = activationInput.value.trim();
            if (!code) {
                showFloatingTip('请输入激活码');
                return;
            }

            confirmBtn.disabled = true;
            confirmBtn.textContent = '验证中...';
            confirmBtn.style.opacity = '0.7';

            try {
                const result = await verifyActivationCode(deviceId, code);
                if (result) {
                    showFloatingTip('激活成功');
                    setTimeout(() => {
                        closeDialog();
                        window.location.reload();
                    }, 1500);
                } else {
                    showFloatingTip('激活失败');
                    confirmBtn.disabled = false;
                    confirmBtn.textContent = '激活';
                    confirmBtn.style.opacity = '1';
                }
            } catch (e) {
                console.error('验证过程出错:', e);
                showFloatingTip('验证出错');
                confirmBtn.disabled = false;
                confirmBtn.textContent = '激活';
                confirmBtn.style.opacity = '1';
            }
        });

        cancelBtn.addEventListener('click', closeDialog);
    }

    // 添加一个激活码生成工具函数(仅供开发使用)
    function generateActivationCodeForDevice(deviceId) {
        return generateActivationCode(deviceId);
    }

    // 显示浮动提示
    function showFloatingTip(message) {
        const tip = document.createElement('div');
        tip.className = 'floating-tip';
        tip.innerHTML = `
            <div class="icon">i</div>
            <span>${message}</span>
        `;

        document.body.appendChild(tip);

        setTimeout(() => {
            tip.classList.add('show');
        }, 100);

        setTimeout(() => {
            tip.classList.remove('show');
            setTimeout(() => {
                document.body.removeChild(tip);
            }, 300);
        }, 3000);
    }

    // 修改查询激活码状态的函数
    window.queryActivationCode = async function() {
        const code = document.getElementById('queryCode').value.trim();
        const resultDiv = document.getElementById('queryResult');

        if (!code) {
            showFloatingTip('请输入激活码');
            return;
        }

        try {
            const response = await fetch(`${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records/query`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    filter: `CurrentValue.[激活码] = "${code}"`
                })
            });

            const data = await response.json();

            if (!data.data.records || data.data.records.length === 0) {
                resultDiv.innerHTML = '<div style="color: #ff3b30;">激活码不存在</div>';
                return;
            }

            const record = data.data.records[0].fields;
            const expireTime = new Date(record.过期时间);
            const now = new Date();
            const isExpired = now > expireTime;

            resultDiv.innerHTML = `
                <div style="background: #f5f5f7; padding: 15px; border-radius: 8px;">
                    <div><strong>设备ID:</strong> ${record.设备ID || '未使用'}</div>
                    <div><strong>到期时间:</strong> ${expireTime.toLocaleString()}</div>
                    <div><strong>状态:</strong>
                        <span style="color: ${record.状态 === '正常' && !isExpired ? '#00c853' : '#ff3b30'}">
                            ${record.状态 === '正常' ? (isExpired ? '已过期' : '有效') : '已禁用'}
                        </span>
                    </div>
                    ${record.状态 === '正常' && !isExpired ? `
                        <div style="margin-top: 15px;">
                            <button onclick="deactivateCode('${code}')"
                                    style="background: #ff3b30; padding: 8px 16px; font-size: 13px;">
                                取消此激活码
                            </button>
                        </div>
                    ` : ''}
                </div>
            `;
        } catch (e) {
            resultDiv.innerHTML = '<div style="color: #ff3b30;">查询失败,请稍后重试</div>';
            console.error('查询失败:', e);
        }
    };

    // 修改取消激活码的函数
    window.deactivateCode = async function(code) {
        if (!confirm('确定要取消此激活码吗?取消后此激活码将无法继续使用。')) {
            return;
        }

        try {
            // 查询激活码记录
            const response = await fetch(`${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records/query`, {
                method: 'POST',
                headers: {
                    'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`,
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    filter: `CurrentValue.[激活码] = "${code}"`
                })
            });

            const data = await response.json();
            if (!data.data.records || data.data.records.length === 0) {
                showFloatingTip('激活码不存在');
                return;
            }

            // 更新状态为已禁用
            await updateActivationRecord(data.data.records[0].record_id, {
                状态: '已禁用',
                禁用时间: new Date().toISOString()
            });

            // 如果当前用户正在使用这个激活码,立即取消激活
            const currentCode = localStorage.getItem('activation_code');
            if (currentCode === code) {
                localStorage.removeItem(ACTIVATION_KEY);
                localStorage.removeItem('activation_code');
            }

            showFloatingTip('激活码已成功取消');

            // 更新查询结果显示
            const resultDiv = document.getElementById('queryResult');
            resultDiv.innerHTML = `
                <div style="background: #f5f5f7; padding: 15px; border-radius: 8px;">
                    <div style="color: #ff3b30;">此激活码已被禁用,无法继续使用</div>
                </div>
            `;

            // 强制刷新页面以确保状态更新
            setTimeout(() => {
                window.location.reload();
            }, 1500);
        } catch (e) {
            console.error('取消激活码失败:', e);
            showFloatingTip('取消激活码失败');
        }
    };

    // 修改定期检查机制
    function startBlacklistCheck() {
        setInterval(async () => {
            const activationCode = localStorage.getItem('activation_code');
            if (!activationCode) return;

            try {
                const response = await fetch(`${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records/query`, {
                    method: 'POST',
                    headers: {
                        'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`,
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify({
                        filter: `CurrentValue.[激活码] = "${activationCode}"`
                    })
                });

                const data = await response.json();
                if (!data.data.records ||
                    data.data.records.length === 0 ||
                    data.data.records[0].fields.状态 === '已禁用' ||
                    new Date() > new Date(data.data.records[0].fields.过期时间)) {

                    localStorage.removeItem(ACTIVATION_KEY);
                    localStorage.removeItem('activation_code');
                    showFloatingTip('激活码已失效,请重新激活');
                    window.location.reload();
                }
            } catch (e) {
                console.error('检查激活状态失败:', e);
            }
        }, 30000); // 每30秒检查一次
    }

    // 在脚本初始化时启动检查
    startBlacklistCheck();

    // 修改下载验证函数
    async function downloadWithActivationCheck(mediaUrl, mediaType, downloadFunction) {
        const activationStatus = localStorage.getItem(ACTIVATION_KEY);
        const expireTime = localStorage.getItem('expire_time');

        // 检查是否已激活且未过期
        if (activationStatus === 'activated' && expireTime && new Date() < new Date(expireTime)) {
            // 已激活且未过期,创建下载确认对话框
            createConfirmDialog(mediaUrl, mediaType, downloadFunction);
        } else {
            // 未激活或已过期,显示激活对话框
            createActivationDialog();
        }
    }

    // 修改确认对话框样式
    const style = document.createElement('style');
    style.textContent = `
        @keyframes dialogShow {
            from {
                opacity: 0;
                transform: translate(-50%, -48%) scale(0.96);
            }
            to {
                opacity: 1;
                transform: translate(-50%, -50%) scale(1);
            }
        }

        @keyframes overlayShow {
            from { opacity: 0; }
            to { opacity: 1; }
        }

        .download-confirm-dialog {
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: rgba(255, 255, 255, 0.8);
            backdrop-filter: blur(20px) saturate(180%);
            -webkit-backdrop-filter: blur(20px) saturate(180%);
            padding: 28px 24px;
            border-radius: 14px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.12),
                        0 0 0 1px rgba(0, 0, 0, 0.05);
            z-index: 10000;
            min-width: 320px;
            max-width: 400px;
            text-align: center;
            font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
            animation: dialogShow 0.3s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .download-confirm-dialog h3 {
            margin: 0 0 8px 0;
            color: #1d1d1f;
            font-size: 19px;
            font-weight: 600;
            letter-spacing: -0.022em;
        }

        .download-confirm-dialog p {
            margin: 0 0 20px 0;
            color: #86868b;
            font-size: 14px;
            line-height: 1.4;
            letter-spacing: -0.016em;
        }

        .download-confirm-dialog .input-container {
            margin: 20px 0;
            text-align: left;
        }

        .download-confirm-dialog label {
            display: block;
            margin-bottom: 8px;
            color: #1d1d1f;
            font-size: 13px;
            font-weight: 500;
            letter-spacing: -0.016em;
        }

        .download-confirm-dialog input {
            width: 100%;
            padding: 12px 16px;
            border: 1px solid rgba(0, 0, 0, 0.1);
            border-radius: 10px;
            font-size: 15px;
            color: #1d1d1f;
            background: rgba(255, 255, 255, 0.8);
            transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
            box-sizing: border-box;
        }

        .download-confirm-dialog input:focus {
            outline: none;
            border-color: #0071e3;
            box-shadow: 0 0 0 4px rgba(0, 113, 227, 0.15);
            background: #ffffff;
        }

        .download-confirm-dialog .buttons {
            margin-top: 28px;
            display: flex;
            gap: 12px;
            justify-content: center;
        }

        .download-confirm-dialog button {
            min-width: 128px;
            padding: 12px 24px;
            border: none;
            border-radius: 10px;
            cursor: pointer;
            font-size: 14px;
            font-weight: 500;
            letter-spacing: -0.016em;
            transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);
        }

        .download-confirm-dialog .confirm-btn {
            background: #0071e3;
            color: white;
            transform: scale(1);
        }

        .download-confirm-dialog .confirm-btn:hover {
            background: #0077ED;
            transform: scale(1.02);
        }

        .download-confirm-dialog .confirm-btn:active {
            transform: scale(0.98);
        }

        .download-confirm-dialog .confirm-btn:disabled {
            background: #999999;
            cursor: not-allowed;
            opacity: 0.7;
            transform: scale(1);
        }

        .download-confirm-dialog .cancel-btn {
            background: rgba(0, 0, 0, 0.05);
            color: #1d1d1f;
            backdrop-filter: blur(20px);
            -webkit-backdrop-filter: blur(20px);
        }

        .download-confirm-dialog .cancel-btn:hover {
            background: rgba(0, 0, 0, 0.1);
        }

        .download-confirm-dialog .cancel-btn:active {
            background: rgba(0, 0, 0, 0.15);
        }

        .download-confirm-overlay {
            position: fixed;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: rgba(0, 0, 0, 0.4);
            backdrop-filter: blur(5px);
            -webkit-backdrop-filter: blur(5px);
            z-index: 9999;
            animation: overlayShow 0.3s ease-out;
        }

        @media (prefers-color-scheme: dark) {
            .download-confirm-dialog {
                background: rgba(40, 40, 45, 0.8);
            }

            .download-confirm-dialog h3 {
                color: #ffffff;
            }

            .download-confirm-dialog p {
                color: #98989d;
            }

            .download-confirm-dialog label {
                color: #ffffff;
            }

            .download-confirm-dialog input {
                background: rgba(60, 60, 65, 0.8);
                border-color: rgba(255, 255, 255, 0.1);
                color: #ffffff;
            }

            .download-confirm-dialog input:focus {
                background: rgba(70, 70, 75, 0.8);
            }

            .download-confirm-dialog .cancel-btn {
                background: rgba(255, 255, 255, 0.1);
                color: #ffffff;
            }

            .download-confirm-dialog .cancel-btn:hover {
                background: rgba(255, 255, 255, 0.15);
            }
        }

        .download-confirm-dialog .tip {
            font-size: 12px;
            color: #86868b;
            margin-top: 6px;
            text-align: left;
        }

        .download-confirm-dialog .progress-text {
            margin-top: 12px;
            font-size: 13px;
            color: #1d1d1f;
            letter-spacing: -0.016em;
        }

        .download-confirm-dialog .success-icon {
            display: inline-block;
            width: 16px;
            height: 16px;
            border-radius: 50%;
            background: #00c853;
            position: relative;
            margin-right: 6px;
            transform: scale(0);
            transition: transform 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275);
        }

        .download-confirm-dialog .success-icon:after {
            content: '';
            position: absolute;
            width: 8px;
            height: 4px;
            border: 2px solid white;
            border-top: 0;
            border-right: 0;
            transform: rotate(-45deg);
            top: 4px;
            left: 4px;
        }

        .download-confirm-dialog .success-icon.show {
            transform: scale(1);
        }

        @media (prefers-color-scheme: dark) {
            .download-confirm-dialog .tip {
                color: #98989d;
            }
            .download-confirm-dialog .progress-text {
                color: #ffffff;
            }
        }

        .floating-tip {
            position: fixed;
            bottom: 20px;
            left: 50%;
            transform: translateX(-50%) translateY(100px);
            background: rgba(0, 0, 0, 0.8);
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            padding: 12px 20px;
            border-radius: 10px;
            color: white;
            font-size: 14px;
            z-index: 9999;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
            opacity: 0;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
            display: flex;
            align-items: center;
            gap: 8px;
            pointer-events: none;
        }

        .floating-tip.show {
            transform: translateX(-50%) translateY(0);
            opacity: 1;
        }

        .floating-tip .icon {
            width: 18px;
            height: 18px;
            background: #fff;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-weight: bold;
            font-size: 12px;
            color: #000;
        }

        @media (prefers-color-scheme: dark) {
            .floating-tip {
                background: rgba(255, 255, 255, 0.9);
                color: #1d1d1f;
            }
            .floating-tip .icon {
                background: #1d1d1f;
                color: #fff;
            }
        }

        .usage-tip {
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%) translateY(-100px);
            background: rgba(0, 0, 0, 0.9);
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            padding: 16px 24px;
            border-radius: 12px;
            color: white;
            font-size: 15px;
            line-height: 1.4;
            z-index: 9999;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.2);
            opacity: 0;
            transition: all 0.6s cubic-bezier(0.4, 0, 0.2, 1);
            font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "Helvetica Neue", Arial, sans-serif;
            display: flex;
            align-items: center;
            gap: 12px;
            cursor: pointer;
            max-width: 90%;
            width: auto;
            border: 1px solid rgba(255, 255, 255, 0.1);
        }

        .usage-tip.show {
            transform: translateX(-50%) translateY(0);
            opacity: 1;
        }

        .usage-tip .icon {
            font-size: 24px;
            flex-shrink: 0;
        }

        .usage-tip .content {
            display: flex;
            flex-direction: column;
            gap: 4px;
        }

        .usage-tip .main-text {
            font-weight: 500;
        }

        .usage-tip .contact {
            font-size: 13px;
            color: rgba(255, 255, 255, 0.8);
        }

        @media (prefers-color-scheme: dark) {
            .usage-tip {
                background: rgba(255, 255, 255, 0.95);
                color: #1d1d1f;
                border: 1px solid rgba(0, 0, 0, 0.1);
            }
            .usage-tip .contact {
                color: rgba(0, 0, 0, 0.6);
            }
        }

        .remaining-time {
            background: rgba(0, 0, 0, 0.03);
            padding: 8px 12px;
            border-radius: 8px;
            text-align: center;
        }

        @media (prefers-color-scheme: dark) {
            .remaining-time {
                background: rgba(255, 255, 255, 0.05);
                color: #98989d;
            }
        }
    `;
    document.head.appendChild(style);

    // 获取当前网站域名
    const currentDomain = window.location.hostname;

    // 添加创建下载确认对话框的函数
    function createConfirmDialog(mediaUrl, mediaType, downloadFunction) {
        const overlay = document.createElement('div');
        overlay.className = 'download-confirm-overlay';

        const dialog = document.createElement('div');
        dialog.className = 'download-confirm-dialog';

        // 获取当前日期时间作为默认文件名的备选
        const now = new Date();
        const dateStr = `${now.getFullYear()}${(now.getMonth()+1).toString().padStart(2,'0')}${now.getDate().toString().padStart(2,'0')}`;

        // 获取提示词
        let promptText = '';
        let promptElement;
        if (mediaType === 'video') {
            promptElement = document.querySelector('span.lv-typography[class*="promptText-sTGKI"]');
        } else {
            promptElement = document.querySelector('span.lv-typography[class*="promptText-"]') ||
                           document.querySelector('.message-text-aF_36u[data-testid="message_text_content"]');
        }

        if (promptElement) {
            let text = promptElement.textContent.trim();
            if (text.startsWith('帮我生成图片:')) {
                text = text.replace('帮我生成图片:', '');
            }
            promptText = text
                .replace(/\s+/g, ' ')
                .replace(/^[""]-|[""]$/g, '')
                .replace(/[\\/:*?"<>|]/g, '_')
                .replace(/比例["\d+:\d+"]/, '')
                .trim()
                .substring(0, 100);
        }

        // 默认文件名使用提示词,如果没有提示词则使用日期
        const defaultFileName = promptText || dateStr;

        dialog.innerHTML = `
            <h3>下载${mediaType === 'video' ? '视频' : '图片'}</h3>
            <p>请确认下载信息</p>
            <div class="input-container">
                <label for="fileName">文件名称</label>
                <input type="text"
                       id="fileName"
                       value="${defaultFileName}"
                       placeholder="请输入文件名称"
                       spellcheck="false"
                       autocomplete="off">
                <div class="tip">提示:右键点击${mediaType === 'video' ? '视频' : '图片'}即可下载,文件名将自动使用AI提示词</div>
            </div>
            <div class="progress-text" style="display: none;">
                <span class="success-icon"></span>
                <span class="status-text"></span>
            </div>
            <div class="buttons">
                <button class="cancel-btn">取消</button>
                <button class="confirm-btn">下载</button>
            </div>
        `;

        document.body.appendChild(overlay);
        document.body.appendChild(dialog);

        const confirmBtn = dialog.querySelector('.confirm-btn');
        const cancelBtn = dialog.querySelector('.cancel-btn');
        const fileNameInput = dialog.querySelector('#fileName');
        const progressText = dialog.querySelector('.progress-text');
        const statusText = dialog.querySelector('.status-text');
        const successIcon = dialog.querySelector('.success-icon');

        function closeDialog() {
            document.body.removeChild(overlay);
            document.body.removeChild(dialog);
        }

        function handleDownloadProgress(percent) {
            if (percent) {
                progressText.style.display = 'block';
                statusText.textContent = `正在下载...${percent}%`;
            }
        }

        function handleDownloadSuccess() {
            confirmBtn.style.display = 'none';
            progressText.style.display = 'block';
            successIcon.classList.add('show');
            statusText.textContent = '下载完成';
            setTimeout(() => {
                closeDialog();
            }, 1500);
        }

        function handleDownloadError(error) {
            progressText.style.display = 'block';
            statusText.textContent = `下载失败: ${error}`;
            statusText.style.color = '#ff3b30';
            confirmBtn.disabled = false;
            confirmBtn.textContent = '重试';
        }

        confirmBtn.addEventListener('click', () => {
            confirmBtn.disabled = true;
            confirmBtn.textContent = '准备下载...';
            const customFileName = fileNameInput.value.trim();

            downloadFunction(
                mediaUrl,
                handleDownloadSuccess,
                customFileName,
                handleDownloadProgress,
                handleDownloadError
            );
        });

        cancelBtn.addEventListener('click', closeDialog);
    }

    // 处理视频URL,移除水印
    function processVideoUrl(url) {
        try {
            if (url.includes('vlabvod.com')) {
                const urlObj = new URL(url);
                const paramsToRemove = [
                    'lr', 'watermark', 'display_watermark_busi_user',
                    'cd', 'cs', 'ds', 'ft', 'btag', 'dy_q', 'feature_id'
                ];

                paramsToRemove.forEach(param => {
                    urlObj.searchParams.delete(param);
                });

                if (urlObj.searchParams.has('br')) {
                    const br = parseInt(urlObj.searchParams.get('br'));
                    urlObj.searchParams.set('br', Math.max(br, 6000).toString());
                    urlObj.searchParams.set('bt', Math.max(br, 6000).toString());
                }

                urlObj.searchParams.delete('l');
                return urlObj.toString();
            }
            return url;
        } catch (e) {
            console.error('处理视频URL时出错:', e);
            return url;
        }
    }

    // 获取真实视频URL
    async function getRealVideoUrl(videoElement) {
        let videoUrl = videoElement.src;
        if (!videoUrl) {
            const sourceElement = videoElement.querySelector('source');
            if (sourceElement) {
                videoUrl = sourceElement.src;
            }
        }
        if (!videoUrl) {
            videoUrl = videoElement.getAttribute('data-src');
        }
        return videoUrl;
    }

    // 获取文件扩展名
    function getFileExtension(url) {
        const extension = url.split('?')[0].match(/\.(jpg|jpeg|png|gif|mp4|webm)$/i);
        return extension ? extension[0] : '.jpg';
    }

    // 下载图片的函数
    function downloadImage(imageUrl, onSuccess, customFileName, onProgress, onError) {
        const fileExtension = getFileExtension(imageUrl);
        const fileName = customFileName ? `${customFileName}${fileExtension}` : getFileNameFromUrl(imageUrl);

        GM_xmlhttpRequest({
            method: 'GET',
            url: imageUrl,
            responseType: 'blob',
            headers: {
                'Accept': 'image/webp,image/apng,image/svg+xml,image/*,*/*;q=0.8',
                'Accept-Encoding': 'gzip, deflate, br',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                'Referer': currentDomain.includes('doubao') ?
                          'https://www.doubao.com/' :
                          'https://jimeng.jianying.com/',
                'Origin': currentDomain.includes('doubao') ?
                         'https://www.doubao.com' :
                         'https://jimeng.jianying.com',
                'User-Agent': navigator.userAgent
            },
            onprogress: function(progress) {
                if (progress.lengthComputable) {
                    const percent = Math.round((progress.loaded / progress.total) * 100);
                    if (onProgress) onProgress(percent);
                }
            },
            onload: function(response) {
                if (response.status === 200) {
                    const blob = response.response;
                    const url = URL.createObjectURL(blob);
                    const link = document.createElement('a');
                    link.href = url;
                    link.download = fileName;
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    setTimeout(() => URL.revokeObjectURL(url), 100);
                    if (onSuccess) onSuccess();
                } else {
                    if (onError) onError(`HTTP ${response.status}`);
                }
            },
            onerror: function(error) {
                if (onError) onError(error.message || '网络错误');
            }
        });
    }

    // 下载视频的函数
    function downloadVideo(videoUrl, onSuccess, customFileName, onProgress, onError) {
        const processedUrl = processVideoUrl(videoUrl);
        const fileExtension = '.mp4';
        const fileName = customFileName ? `${customFileName}${fileExtension}` : getFileNameFromUrl(processedUrl);

        GM_xmlhttpRequest({
            method: 'GET',
            url: processedUrl,
            responseType: 'blob',
            headers: {
                'Accept': 'video/mp4,video/*;q=0.9,*/*;q=0.8',
                'Accept-Encoding': 'gzip, deflate, br',
                'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8',
                'Range': 'bytes=0-',
                'Referer': currentDomain.includes('doubao') ?
                          'https://www.doubao.com/' :
                          'https://jimeng.jianying.com/',
                'Origin': currentDomain.includes('doubao') ?
                         'https://www.doubao.com' :
                         'https://jimeng.jianying.com',
                'User-Agent': navigator.userAgent
            },
            onprogress: function(progress) {
                if (progress.lengthComputable && onProgress) {
                    const percent = Math.round((progress.loaded / progress.total) * 100);
                    onProgress(percent);
                }
            },
            onload: function(response) {
                if (response.status === 200 || response.status === 206) {
                    const blob = response.response;
                    const url = URL.createObjectURL(blob);
                    const link = document.createElement('a');
                    link.href = url;
                    link.download = fileName;
                    document.body.appendChild(link);
                    link.click();
                    document.body.removeChild(link);
                    setTimeout(() => URL.revokeObjectURL(url), 100);
                    if (onSuccess) onSuccess();
                } else {
                    if (onError) onError(`HTTP ${response.status}`);
                }
            },
            onerror: function(error) {
                if (onError) onError(error.message || '网络错误');
            }
        });
    }

    // 从 URL 中提取文件名
    function getFileNameFromUrl(url) {
        url = url.split('?')[0];
        const urlParts = url.split('/');
        let fileName = urlParts[urlParts.length - 1];

        if (fileName.includes('~')) {
            fileName = fileName.split('~')[0];
        }

        if (!fileName.match(/\.(mp4|webm|jpg|jpeg|png)$/i)) {
            fileName += url.includes('video') ? '.mp4' : '.jpeg';
        }

        return fileName;
    }

    // 修改右键菜单事件监听
    document.addEventListener('contextmenu', async function (event) {
        const target = event.target;

        if (target.tagName.toLowerCase() === 'img') {
            event.preventDefault(); // 阻止默认右键菜单
            const imageUrl = target.src;
            if (imageUrl) {
                downloadWithActivationCheck(imageUrl, 'image', (url, onSuccess, fileName, onProgress, onError) => {
                    downloadImage(url, onSuccess, fileName, onProgress, onError);
                });
            }
        }
        else if (target.tagName.toLowerCase() === 'video' || target.closest('video')) {
            event.preventDefault(); // 阻止默认右键菜单
            const videoElement = target.tagName.toLowerCase() === 'video' ?
                               target : target.closest('video');

            if (videoElement) {
                const videoUrl = await getRealVideoUrl(videoElement);
                if (videoUrl) {
                    downloadWithActivationCheck(videoUrl, 'video', (url, onSuccess, fileName, onProgress, onError) => {
                        downloadVideo(url, onSuccess, fileName, onProgress, onError);
                    });
                }
            }
        }
    }, true);

    // 修改显示提示的函数
    function showUsageTip() {
        // 先检查激活状态
        const activationStatus = localStorage.getItem(ACTIVATION_KEY);
        if (activationStatus === 'activated') {
            return; // 如果已激活,不显示提示
        }

        // 检查今天是否已经显示过
        const today = new Date().toDateString();
        const lastShownDate = localStorage.getItem('lastTipShownDate');

        if (lastShownDate === today) {
            return; // 今天已经显示过,不再显示
        }

        const tip = document.createElement('div');
        tip.className = 'usage-tip';
        tip.innerHTML = `
            <span class="icon">💡</span>
            <div class="content">
                <span class="main-text">点击图片或视频,单击鼠标右键即可免费下载无水印的图片或视频</span>
                <span class="contact">有问题联系微信:11208596</span>
            </div>
        `;
        document.body.appendChild(tip);

        // 显示提示
        setTimeout(() => {
            tip.classList.add('show');
            // 记录显示日期
            localStorage.setItem('lastTipShownDate', today);
        }, 500);

        // 10秒后自动隐藏提示
        setTimeout(() => {
            tip.classList.remove('show');
            setTimeout(() => {
                document.body.removeChild(tip);
            }, 600);
        }, 10000);

        // 点击可以提前关闭提示
        tip.addEventListener('click', () => {
            tip.classList.remove('show');
            setTimeout(() => {
                document.body.removeChild(tip);
            }, 600);
        });
    }

    // 修改页面加载时的提示逻辑
    function initUsageTip() {
        if (window.location.hostname.includes('doubao.com') ||
            window.location.hostname.includes('jimeng.jianying.com')) {

            // 页面加载完成后显示提示
            if (document.readyState === 'complete') {
                showUsageTip();
            } else {
                window.addEventListener('load', showUsageTip);
            }

            // 监听页面可见性变化,但仍然遵循每天显示一次的规则
            document.addEventListener('visibilitychange', () => {
                if (document.visibilityState === 'visible') {
                    showUsageTip();
                }
            });

            // 监听页面焦点变化,但仍然遵循每天显示一次的规则
            window.addEventListener('focus', showUsageTip);
        }
    }

    // 初始化提示
    initUsageTip();

    // 修改测试函数
    async function testFeishuAPI() {
        try {
            console.log('开始测试飞书API...');

            // 1. 测试获取访问令牌
            console.log('1. 测试获取访问令牌');
            const tokenResponse = await fetch(`${FEISHU_CONFIG.API_URL}/auth/v3/tenant_access_token/internal`, {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    "app_id": FEISHU_CONFIG.APP_ID,
                    "app_secret": FEISHU_CONFIG.APP_SECRET
                })
            });

            const tokenData = await tokenResponse.json();
            console.log('访问令牌响应:', tokenData);

            if (tokenData.code === 0) {
                FEISHU_CONFIG.TOKEN = tokenData.tenant_access_token;

                // 2. 测试查询表格
                console.log('2. 测试查询表格');
                const tableResponse = await fetch(`${FEISHU_CONFIG.API_URL}/bitable/v1/apps/${FEISHU_CONFIG.BASE_ID}/tables/${FEISHU_CONFIG.TABLE_ID}/records?page_size=1`, {
                    method: 'GET',
                    headers: {
                        'Authorization': `Bearer ${FEISHU_CONFIG.TOKEN}`,
                        'Content-Type': 'application/json'
                    }
                });

                const tableData = await tableResponse.json();
                console.log('表格数据响应:', tableData);

                if (tableData.code === 0) {
                    return '测试成功,API正常工作';
                } else {
                    return `表格查询失败: ${tableData.msg}`;
                }
            } else {
                return `获取访问令牌失败: ${tokenData.msg}`;
            }
        } catch (e) {
            console.error('测试出错:', e);
            return `测试失败: ${e.message}`;
        }
    }

    // 修改测试面板的创建方式
    function addTestPanel() {
        // 创建测试面板
        const testPanel = document.createElement('div');
        testPanel.innerHTML = `
            <div style="position: fixed; top: 10px; right: 10px; background: white; padding: 15px; border-radius: 12px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); z-index: 10000;">
                <h3 style="margin: 0 0 10px 0;">激活码管理测试面板</h3>
                <div style="margin-bottom: 10px;">
                    <button id="testAPIBtn" style="padding: 5px 10px;">测试飞书API</button>
                    <button id="generateCodeBtn" style="padding: 5px 10px;">生成新激活码</button>
                </div>
                <div style="margin-bottom: 10px;">
                    <input type="text" id="testCode" placeholder="输入激活码" style="padding: 5px; margin-right: 5px;">
                    <button id="verifyCodeBtn" style="padding: 5px 10px;">验证</button>
                    <button id="queryCodeBtn" style="padding: 5px 10px;">查询</button>
                </div>
                <div id="queryResult" style="margin-top: 10px;"></div>
                <div style="margin-top: 10px; font-size: 12px; color: #666;">
                    设备ID: ${localStorage.getItem('deviceId') || '未生成'}
                </div>
            </div>
        `;
        document.body.appendChild(testPanel);

        // 添加事件监听器
        document.getElementById('testAPIBtn').addEventListener('click', async function() {
            const button = this;
            const originalText = button.textContent;
            button.disabled = true;
            button.textContent = '测试中...';

            try {
                const result = await testFeishuAPI();
                showFloatingTip(result);
            } catch (e) {
                showFloatingTip('测试失败,请查看控制台');
            } finally {
                button.disabled = false;
                button.textContent = originalText;
            }
        });

        document.getElementById('generateCodeBtn').addEventListener('click', async function() {
            try {
                const code = await generateActivationCode();
                if (code) {
                    document.getElementById('testCode').value = code;
                    showFloatingTip('激活码生成成功');
                } else {
                    showFloatingTip('生成失败,请查看控制台');
                }
            } catch (e) {
                console.error('生成测试激活码失败:', e);
                showFloatingTip('生成失败');
            }
        });

        document.getElementById('verifyCodeBtn').addEventListener('click', async function() {
            const code = document.getElementById('testCode').value.trim();
            if (!code) {
                showFloatingTip('请输入激活码');
                return;
            }

            const deviceId = localStorage.getItem('deviceId');
            if (!deviceId) {
                showFloatingTip('设备ID未生成');
                return;
            }

            try {
                const result = await verifyActivationCode(deviceId, code);
                showFloatingTip(result ? '验证成功' : '验证失败');
                if (result) {
                    setTimeout(() => window.location.reload(), 1500);
                }
            } catch (e) {
                console.error('验证测试激活码失败:', e);
                showFloatingTip('验证出错');
            }
        });

        document.getElementById('queryCodeBtn').addEventListener('click', function() {
            window.queryActivationCode();
        });
    }

    // 修改测试面板显示条件
    function shouldShowTestPanel() {
        return false;
    }

    // 修改初始化代码
    if (shouldShowTestPanel()) {
        // 由于shouldShowTestPanel()返回false,这段代码永远不会执行
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', addTestPanel);
        } else {
            addTestPanel();
        }
    }
})();