123pan JSON秒传链接工具

优化版:更稳定

当前为 2025-07-13 提交的版本,查看 最新版本

// ==UserScript==
// @name         123pan JSON秒传链接工具
// @namespace    http://tampermonkey.net/
// @version      1.1.1
// @description  优化版:更稳定
// @author       Tocpomk
// @match        *://*.123pan.com/*
// @match        *://*.123pan.cn/*
// @match        *://*.123865.com/*
// @match        *://*.123912.com/*
// @grant        GM_addStyle
// @grant        GM_setValue
// @grant        GM_getValue
// @run-at       document-end
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // 添加样式
    GM_addStyle(`
        #json-tool-float-btn {
            position: fixed;
            top: 50%;
            right: 20px;
            transform: translateY(-50%);
            width: 60px;
            height: 60px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            border: none;
            border-radius: 50%;
            color: white;
            font-size: 24px;
            cursor: pointer;
            box-shadow: 0 4px 15px rgba(0,0,0,0.2);
            z-index: 9999;
            transition: all 0.3s ease;
            display: flex;
            align-items: center;
            justify-content: center;
            user-select: none;
            animation: pulse 2s infinite;
            touch-action: none;
        }

        #json-tool-float-btn:hover {
            transform: translateY(-50%) scale(1.1);
            box-shadow: 0 6px 20px rgba(0,0,0,0.3);
        }

        #json-tool-float-btn:active {
            transform: translateY(-50%) scale(0.95);
        }

        #json-tool-float-btn.dragging {
            opacity: 0.8;
            cursor: grabbing;
            transform: none !important;
            box-shadow: 0 8px 25px rgba(0,0,0,0.4);
        }

        #json-tool-modal {
            position: fixed;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background: rgba(0,0,0,0.5);
            z-index: 10000;
            display: flex;
            align-items: center;
            justify-content: center;
            opacity: 0;
            visibility: hidden;
            transition: all 0.4s cubic-bezier(0.32, 0.72, 0, 1);
            pointer-events: none;
        }

        #json-tool-modal.show {
            opacity: 1;
            visibility: visible;
            pointer-events: all;
        }

        #json-tool-content {
            width: 90%;
            height: 90%;
            max-width: 1200px;
            background: white;
            border-radius: 16px;
            box-shadow: 0 25px 50px -12px rgba(0,0,0,0.25);
            display: flex;
            flex-direction: column;
            overflow: hidden;
            transform: translateY(50px) scale(0.95);
            opacity: 0;
            transition: all 0.5s cubic-bezier(0.32, 0.72, 0, 1);
        }

        #json-tool-modal.show #json-tool-content {
            transform: translateY(0) scale(1);
            opacity: 1;
        }

        #json-tool-close {
            position: absolute;
            top: 18px;
            right: 18px;
            background: rgba(0,0,0,0.2);
            border: none;
            color: white;
            font-size: 26px;
            cursor: pointer;
            width: 42px;
            height: 42px;
            border-radius: 50%;
            transition: all 0.3s ease;
            z-index: 10001;
            display: flex;
            align-items: center;
            justify-content: center;
        }

        #json-tool-close:hover {
            background: rgba(0,0,0,0.5);
            transform: scale(1.15) rotate(90deg);
        }

        #json-tool-iframe {
            width: 100%;
            height: 100%;
            border: none;
            border-radius: 0 0 16px 16px;
        }

        #json-tool-header {
            height: 60px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            display: flex;
            align-items: center;
            justify-content: space-between;
            padding: 0 24px;
            color: white;
            font-weight: bold;
            font-size: 18px;
        }

        #json-tool-title {
            display: flex;
            align-items: center;
            gap: 12px;
        }

        #json-tool-title svg {
            width: 24px;
            height: 24px;
            fill: white;
        }

        .json-tool-drag-handle {
            width: 100%;
            height: 30px;
            position: absolute;
            top: 0;
            left: 0;
            cursor: move;
            z-index: 1;
        }

        /* 响应式设计 */
        @media (max-width: 768px) {
            #json-tool-content {
                width: 95%;
                height: 95%;
            }

            #json-tool-float-btn {
                width: 50px;
                height: 50px;
                font-size: 20px;
                right: 15px;
            }

            #json-tool-header {
                padding: 0 15px;
                height: 50px;
                font-size: 16px;
            }
        }

        @keyframes pulse {
            0% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0.6); }
            70% { box-shadow: 0 0 0 12px rgba(102, 126, 234, 0); }
            100% { box-shadow: 0 0 0 0 rgba(102, 126, 234, 0); }
        }

        .json-tool-tooltip {
            position: absolute;
            top: -45px;
            left: 50%;
            transform: translateX(-50%);
            background: rgba(0,0,0,0.7);
            color: white;
            padding: 8px 12px;
            border-radius: 6px;
            font-size: 14px;
            white-space: nowrap;
            pointer-events: none;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .json-tool-tooltip::after {
            content: '';
            position: absolute;
            top: 100%;
            left: 50%;
            transform: translateX(-50%);
            border-width: 6px;
            border-style: solid;
            border-color: rgba(0,0,0,0.7) transparent transparent transparent;
        }

        #json-tool-float-btn:hover .json-tool-tooltip {
            opacity: 1;
        }
    `);

    // 创建悬浮按钮
    function createFloatButton() {
        const btn = document.createElement('button');
        btn.id = 'json-tool-float-btn';
        btn.innerHTML = `
            🔗
            <div class="json-tool-tooltip">拖拽移动位置</div>
        `;
        btn.title = 'JSON秒传链接工具';

        // 从存储中获取位置
        const savedPosition = GM_getValue('floatButtonPosition', null);
        if (savedPosition) {
            btn.style.left = `${savedPosition.x}px`;
            btn.style.top = `${savedPosition.y}px`;
            btn.style.right = 'auto';
            btn.style.transform = 'none';
        }

        // 添加拖拽功能
        let isDragging = false;
        let dragOffsetX, dragOffsetY;

        btn.addEventListener('mousedown', startDrag);
        btn.addEventListener('touchstart', startDragTouch, { passive: false });

        function startDrag(e) {
            e.preventDefault();
            isDragging = true;
            btn.classList.add('dragging');
            const rect = btn.getBoundingClientRect();
            dragOffsetX = e.clientX - rect.left;
            dragOffsetY = e.clientY - rect.top;

            document.addEventListener('mousemove', onDrag);
            document.addEventListener('mouseup', stopDrag);
        }

        function startDragTouch(e) {
            if (e.touches.length !== 1) return;
            e.preventDefault();
            isDragging = true;
            btn.classList.add('dragging');
            const touch = e.touches[0];
            const rect = btn.getBoundingClientRect();
            dragOffsetX = touch.clientX - rect.left;
            dragOffsetY = touch.clientY - rect.top;

            document.addEventListener('touchmove', onDragTouch, { passive: false });
            document.addEventListener('touchend', stopDrag);
        }

        function onDrag(e) {
            if (!isDragging) return;
            e.preventDefault();
            updatePosition(e.clientX, e.clientY);
        }

        function onDragTouch(e) {
            if (!isDragging || e.touches.length !== 1) return;
            e.preventDefault();
            const touch = e.touches[0];
            updatePosition(touch.clientX, touch.clientY);
        }

        function updatePosition(clientX, clientY) {
            const x = clientX - dragOffsetX;
            const y = clientY - dragOffsetY;

            // 限制按钮不超出屏幕边界
            const maxX = window.innerWidth - btn.offsetWidth;
            const maxY = window.innerHeight - btn.offsetHeight;

            btn.style.left = `${Math.max(0, Math.min(x, maxX))}px`;
            btn.style.top = `${Math.max(0, Math.min(y, maxY))}px`;
            btn.style.right = 'auto';
            btn.style.transform = 'none';
        }

        function stopDrag() {
            if (!isDragging) return;
            isDragging = false;
            btn.classList.remove('dragging');

            // 保存位置
            GM_setValue('floatButtonPosition', {
                x: parseInt(btn.style.left),
                y: parseInt(btn.style.top)
            });

            document.removeEventListener('mousemove', onDrag);
            document.removeEventListener('touchmove', onDragTouch);
            document.removeEventListener('mouseup', stopDrag);
            document.removeEventListener('touchend', stopDrag);
        }

        // 点击事件
        btn.addEventListener('click', function(e) {
            if (!isDragging) {
                showModal();
            }
        });

        document.body.appendChild(btn);
        return btn;
    }

    // 创建弹窗
    function createModal() {
        const modal = document.createElement('div');
        modal.id = 'json-tool-modal';

        modal.innerHTML = `
            <div id="json-tool-content">
                <div class="json-tool-drag-handle"></div>
                <div id="json-tool-header">
                    <div id="json-tool-title">
                        <svg viewBox="0 0 24 24">
                            <path d="M14,11H10V9h4V11z M14,8H10V6h4V8z M20,4V20H4V4H20 M20,2H4C2.9,2,2,2.9,2,4v16c0,1.1,0.9,2,2,2h16c1.1,0,2-0.9,2-2V4 C22,2.9,21.1,2,20,2L20,2z M16,15H8v-2h8V15z M16,18H8v-2h8V18z M6,15H4v2h2V15z M6,18H4v2h2V18z M6,6H4v8h2V6z"></path>
                        </svg>
                        <span>JSON秒传链接工具</span>
                    </div>
                    <button id="json-tool-close">×</button>
                </div>
                <iframe id="json-tool-iframe" src="https://123.487510.xyz/"></iframe>
            </div>
        `;

        // 关闭按钮事件
        modal.querySelector('#json-tool-close').addEventListener('click', hideModal);

        // 点击背景关闭
        modal.addEventListener('click', function(e) {
            if (e.target === modal) {
                hideModal();
            }
        });

        // ESC键关闭
        document.addEventListener('keydown', function(e) {
            if (e.key === 'Escape') {
                hideModal();
            }
        });

        // 添加弹窗拖拽功能
        let isModalDragging = false;
        let modalStartX, modalStartY;
        const dragHandle = modal.querySelector('.json-tool-drag-handle');
        const content = modal.querySelector('#json-tool-content');

        dragHandle.addEventListener('mousedown', startModalDrag);

        function startModalDrag(e) {
            isModalDragging = true;
            modalStartX = e.clientX;
            modalStartY = e.clientY;
            content.style.transition = 'none'; // 拖动时禁用过渡效果
            document.addEventListener('mousemove', onModalDrag);
            document.addEventListener('mouseup', stopModalDrag);
        }

        function onModalDrag(e) {
            if (!isModalDragging) return;
            const deltaX = e.clientX - modalStartX;
            const deltaY = e.clientY - modalStartY;
            content.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
        }

        function stopModalDrag() {
            if (!isModalDragging) return;
            isModalDragging = false;
            content.style.transition = '';
            content.style.transform = '';
            document.removeEventListener('mousemove', onModalDrag);
            document.removeEventListener('mouseup', stopModalDrag);
        }

        document.body.appendChild(modal);
        return modal;
    }

    // 显示弹窗
    function showModal() {
        const modal = document.getElementById('json-tool-modal');
        if (modal) {
            document.body.style.overflow = 'hidden';
            setTimeout(() => {
                modal.classList.add('show');
            }, 10);
        }
    }

    // 隐藏弹窗
    function hideModal() {
        const modal = document.getElementById('json-tool-modal');
        if (modal) {
            modal.classList.remove('show');
            setTimeout(() => {
                document.body.style.overflow = '';
            }, 300); // 匹配动画时间
        }
    }

    // 初始化
    function init() {
        // 等待页面加载完成
        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', function() {
                createFloatButton();
                createModal();
            });
        } else {
            createFloatButton();
            createModal();
        }
    }

    // 启动脚本
    init();
})();