// ==UserScript== // @name o2o编辑系统多语言切换 (支持拖拽+自动预加载) // @namespace https://bbs.tampermonkey.net.cn/ // @version 1.2.0 // @description 页面加载时自动获取同routingName页面,点击按钮直接展示,支持UI拖拽 // @author You // @match https://o2omanage.o2o.co/manage/siteEdit/buildWeb/* // @grant GM_xmlhttpRequest // @grant GM_addStyle // @connect products-api-o2o-prod.gs-souvenir.com // ==/UserScript== (function() { 'use strict'; // 样式注入 GM_addStyle(` #o2o-page-helper-btn { position: fixed; top: 10px; left: 60%; z-index: 99999; background: #1890ff; color: white; padding: 10px 15px; border-radius: 4px; cursor: move; box-shadow: 0 4px 12px rgba(0,0,0,0.2); font-size: 14px; user-select: none; transition: background 0.2s, box-shadow 0.2s; } #o2o-page-helper-btn:active { box-shadow: 0 2px 6px rgba(0,0,0,0.3); } #o2o-page-helper-panel { position: fixed; top: 53px; left: 60%; z-index: 99999; background: white; border: 1px solid #ddd; border-radius: 4px; box-shadow: 0 4px 16px rgba(0,0,0,0.2); width: 300px; max-height: 400px; display: none; /* 默认隐藏 */ font-family: Arial, sans-serif; flex-direction: column; } .o2o-panel-header { padding: 10px; border-bottom: 1px solid #eee; font-weight: bold; display: flex; justify-content: space-between; background: #f5f5f5; cursor: move; user-select: none; } .o2o-content { overflow-y: auto; flex: 1; min-height: 50px; } .o2o-close-btn { cursor: pointer; color: #999; padding: 0 5px; } .o2o-close-btn:hover { color: #333; } .o2o-list-item { padding: 10px; border-bottom: 1px solid #f0f0f0; cursor: pointer; transition: background 0.2s; display: block; text-decoration: none; color: #333; } .o2o-list-item:hover { background: #e6f7ff; } .o2o-tag { background: #e6f7ff; color: #1890ff; border: 1px solid #91d5ff; padding: 2px 6px; border-radius: 4px; font-size: 12px; margin-right: 8px; } .o2o-current { background: #fffbe6; } .o2o-loading { padding: 15px; text-align: center; color: #666; font-size: 13px; } .o2o-error { padding: 15px; color: red; font-size: 13px; } `); // --- 通用拖拽函数 --- function makeDraggable(element, handle) { let isDragging = false; let startX, startY, initialLeft, initialTop; const dragHandle = handle || element; dragHandle.addEventListener('mousedown', (e) => { if (e.target.classList.contains('o2o-close-btn')) return; isDragging = true; startX = e.clientX; startY = e.clientY; const rect = element.getBoundingClientRect(); initialLeft = rect.left; initialTop = rect.top; element.style.right = 'auto'; element.style.bottom = 'auto'; element.style.left = `${initialLeft}px`; element.style.top = `${initialTop}px`; dragHandle.style.cursor = 'grabbing'; element.dataset.isDragging = "true"; element.dataset.hasMoved = "false"; }); document.addEventListener('mousemove', (e) => { if (!isDragging) return; e.preventDefault(); const dx = e.clientX - startX; const dy = e.clientY - startY; if (Math.abs(dx) > 2 || Math.abs(dy) > 2) { element.dataset.hasMoved = "true"; } element.style.left = `${initialLeft + dx}px`; element.style.top = `${initialTop + dy}px`; }); document.addEventListener('mouseup', () => { if (isDragging) { isDragging = false; dragHandle.style.cursor = 'move'; setTimeout(() => { element.dataset.isDragging = "false"; }, 0); } }); } function getCookie(name) { const value = `; ${document.cookie}`; const parts = value.split(`; ${name}=`); if (parts.length === 2) return parts.pop().split(';').shift(); return null; } function getQueryParam(name) { const urlParams = new URLSearchParams(window.location.search); return urlParams.get(name); } // --- 核心逻辑:获取数据并渲染到DOM (但不强制显示) --- function fetchDataAndBuildDom() { const panel = document.querySelector('#o2o-page-helper-panel'); const contentDiv = panel.querySelector('.o2o-content'); // 设置初始加载状态 contentDiv.innerHTML = '