// ==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 = '
数据自动加载中...
'; const currentId = getQueryParam('id'); const token = getCookie('manageToken'); const proId = getCookie('otoManageProId'); if (!currentId) { contentDiv.innerHTML = '
未检测到 URL 参数 id,请在编辑页使用。
'; return; } if (!token || !proId) { contentDiv.innerHTML = '
未检测到 Token 或 ProId,请刷新页面重试。
'; return; } GM_xmlhttpRequest({ method: "POST", url: "https://products-api-o2o-prod.gs-souvenir.com/retailer/page/listAllPagesNoTree", headers: { "accept": "application/json, text/plain, */*", "content-type": "application/json;charset=UTF-8", "token": token }, data: JSON.stringify({ "proId": parseInt(proId), "language": "en-us" }), onload: function(response) { try { if (response.status !== 200) { throw new Error('API请求失败: ' + response.statusText); } const res = JSON.parse(response.responseText); const list = res.data; if (!Array.isArray(list)) { throw new Error('返回数据格式不是数组'); } const currentPageObj = list.find(item => item.id == currentId); if (!currentPageObj) { contentDiv.innerHTML = `
未找到当前ID (${currentId}) 对应的页面数据。
`; return; } // 使用 routingName 过滤 const targetRoutingName = currentPageObj.routingName; const filteredList = list.filter(item => item.routingName === targetRoutingName); if (filteredList.length === 0) { contentDiv.innerHTML = '
没有找到同系列页面。
'; } else { let html = ''; filteredList.forEach(item => { const link = `https://o2omanage.o2o.co/manage/siteEdit/buildWeb/?id=${item.id}&type=1&language=${item.language}`; const isCurrent = item.id == currentId ? 'o2o-current' : ''; html += `
${item.language} ${isCurrent ? '(当前)' : ''}
${item.pageName}
${item.routingName}
`; }); contentDiv.innerHTML = html; } } catch (e) { console.error(e); contentDiv.innerHTML = `
处理出错: ${e.message}
`; } }, onerror: function(err) { console.error(err); contentDiv.innerHTML = '
网络请求发生错误。
'; } }); } // 初始化UI function initUI() { // 创建触发按钮 const btn = document.createElement('div'); btn.id = 'o2o-page-helper-btn'; btn.innerText = '🔍 查找所有语言页面'; // 点击事件:仅仅控制显示/隐藏,不触发请求 btn.onclick = (e) => { if (btn.dataset.hasMoved === "true") return; // 拖拽时不触发 const panel = document.getElementById('o2o-page-helper-panel'); if (panel.style.display === 'none' || panel.style.display === '') { panel.style.display = 'flex'; } else { panel.style.display = 'none'; } }; document.body.appendChild(btn); // 创建展示面板 (初始内容为空或Loading,数据由 fetchDataAndBuildDom 填充) const panel = document.createElement('div'); panel.id = 'o2o-page-helper-panel'; panel.innerHTML = `
页面列表
`; document.body.appendChild(panel); // 应用拖拽逻辑 makeDraggable(btn); makeDraggable(panel, panel.querySelector('.o2o-panel-header')); // 核心修改:UI初始化完毕后,立即发起请求,不等待用户点击 fetchDataAndBuildDom(); } // 启动 initUI(); })();