功能: 优化油猴脚本 v3.0

主要改进:
1. 修复核心Bug - 正确检测API响应状态(检查success字段)
2. 配置界面化 - 使用GM_setValue/GM_getValue持久化存储
3. 添加可视化配置面板 - 无需修改代码
4. 增强错误处理 - 显示详细的错误信息
5. API兼容性验证 - 与后端完全兼容

提供两个版本:
- clients/userscript-template.js (v3.0增强版, 608行)
- client/userscript-template.js (v2.0简化版, 431行)

新增文档:
- USERSCRIPT_CHANGELOG.md - 更新日志
- USERSCRIPT_FIX_SUMMARY.md - 修复总结
- USERSCRIPT_USAGE.md - 使用指南

由Claude Code完成。
This commit is contained in:
2026-08-14 10:15:31 +08:00
parent 9271bf62b2
commit a3c23970d7
5 changed files with 1103 additions and 41 deletions
+131 -10
View File
@@ -1,25 +1,51 @@
// ==UserScript==
// @name 通用数据同步助手
// @namespace http://tampermonkey.net/
// @version 1.0.0
// @description 一键同步 Cookie/Token 到服务器(通用版)
// @version 2.0.0
// @description 一键同步 Cookie/Token 到服务器(通用版),支持可视化配置管理
// @author K-hermes
// @match https://tingwu.aliyun.com/*
// @match https://mp.weixin.qq.com/*
// @grant GM_xmlhttpRequest
// @grant GM_setClipboard
// @grant GM_setValue
// @grant GM_getValue
// @connect 47.122.126.244
// @connect *
// ==/UserScript==
(function() {
'use strict';
// ==================== 配置 ====================
const CONFIG = {
// ==================== 配置管理 ====================
const DEFAULT_CONFIG = {
serverUrl: 'http://47.122.126.244:5001',
password: 'admin123123123',
autoDetect: true // 自动检测项目名和账号
autoDetect: true
};
// 加载配置
function loadConfig() {
const saved = GM_getValue('sync_config', null);
if (saved) {
try {
return {...DEFAULT_CONFIG, ...JSON.parse(saved)};
} catch (e) {
console.error('[同步助手] 配置解析失败,使用默认配置', e);
}
}
return {...DEFAULT_CONFIG};
}
// 保存配置
function saveConfig(config) {
GM_setValue('sync_config', JSON.stringify(config));
console.log('[同步助手] 配置已保存');
}
// 全局配置对象
let CONFIG = loadConfig();
// ==================== 项目检测 ====================
const PROJECT_PATTERNS = {
'tingwu.aliyun.com': {
@@ -124,15 +150,25 @@
},
data: JSON.stringify(data),
onload: function(response) {
if (response.status === 200) {
const result = JSON.parse(response.responseText);
showMessage(`✅ 同步成功!\n\nTag: ${tag}\n过期时间: ${result.expires_at}`, 'success');
let result;
try {
result = JSON.parse(response.responseText);
} catch (e) {
showMessage('❌ 服务器响应格式错误', 'error');
return;
}
// 检查是否成功:HTTP 200 且响应体包含 success: true
if (response.status === 200 && result.success === true) {
showMessage(`✅ 同步成功!\n\nTag: ${tag}\n时间: ${result.timestamp || '未知'}`, 'success');
} else {
showMessage(`❌ 同步失败: ${response.statusText}`, 'error');
// 失败:可能是 HTTP 错误码,或响应包含 error 字段
const errorMsg = result.error || result.message || response.statusText || '未知错误';
showMessage(`❌ 同步失败\n\n状态码: ${response.status}\n错误: ${errorMsg}`, 'error');
}
},
onerror: function(error) {
showMessage(`❌ 网络错误: ${error.error}`, 'error');
showMessage(`❌ 网络错误: ${error.error || '无法连接到服务器'}`, 'error');
}
});
}
@@ -217,6 +253,7 @@
<div id="sync-helper-menu">
<div class="sync-menu-item" id="sync-now">🔄 立即同步</div>
<div class="sync-menu-item" id="copy-config">📋 复制配置</div>
<div class="sync-menu-item" id="open-settings">⚙️ 配置设置</div>
</div>
`;
document.body.appendChild(button);
@@ -239,6 +276,11 @@
copyConfig();
});
document.getElementById('open-settings').addEventListener('click', () => {
menu.style.display = 'none';
showSettingsPanel();
});
// 点击外部关闭菜单
document.addEventListener('click', (e) => {
if (!btn.contains(e.target) && !menu.contains(e.target)) {
@@ -247,6 +289,85 @@
});
}
function showSettingsPanel() {
const panel = document.createElement('div');
panel.id = 'sync-settings-panel';
panel.innerHTML = `
<div style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,0.5); z-index: 999998; display: flex; align-items: center; justify-content: center;">
<div style="background: white; padding: 25px; border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,0.3); max-width: 450px; width: 90%;">
<h3 style="margin: 0 0 20px 0; color: #333; font-size: 18px;">配置设置</h3>
<div style="margin-bottom: 15px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold; color: #555; font-size: 13px;">服务器地址</label>
<input type="text" id="settings-serverUrl" value="${CONFIG.serverUrl}"
style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; box-sizing: border-box; font-size: 14px;">
</div>
<div style="margin-bottom: 15px;">
<label style="display: block; margin-bottom: 5px; font-weight: bold; color: #555; font-size: 13px;">密码</label>
<input type="password" id="settings-password" value="${CONFIG.password}"
style="width: 100%; padding: 10px; border: 1px solid #ddd; border-radius: 6px; box-sizing: border-box; font-size: 14px;">
</div>
<div style="margin-bottom: 20px;">
<label style="display: flex; align-items: center; cursor: pointer;">
<input type="checkbox" id="settings-autoDetect" ${CONFIG.autoDetect ? 'checked' : ''}
style="margin-right: 8px; width: 18px; height: 18px;">
<span style="font-weight: bold; color: #555; font-size: 13px;">自动检测项目和账号</span>
</label>
</div>
<div style="display: flex; gap: 10px;">
<button id="settings-save" style="flex: 1; padding: 12px; background: #4CAF50; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 14px;">
✅ 保存
</button>
<button id="settings-reset" style="flex: 1; padding: 12px; background: #FF9800; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 14px;">
🔄 重置
</button>
<button id="settings-close" style="padding: 12px 20px; background: #f44336; color: white; border: none; border-radius: 6px; cursor: pointer; font-weight: bold; font-size: 14px;">
关闭
</button>
</div>
</div>
</div>
`;
document.body.appendChild(panel);
// 绑定事件
document.getElementById('settings-save').addEventListener('click', () => {
const newConfig = {
serverUrl: document.getElementById('settings-serverUrl').value.trim(),
password: document.getElementById('settings-password').value,
autoDetect: document.getElementById('settings-autoDetect').checked
};
CONFIG = newConfig;
saveConfig(newConfig);
showMessage('✅ 配置已保存', 'success');
panel.remove();
});
document.getElementById('settings-reset').addEventListener('click', () => {
if (confirm('确定要恢复默认配置吗?')) {
CONFIG = {...DEFAULT_CONFIG};
saveConfig(CONFIG);
showMessage('✅ 配置已重置', 'success');
panel.remove();
}
});
document.getElementById('settings-close').addEventListener('click', () => {
panel.remove();
});
// 点击背景关闭
panel.addEventListener('click', (e) => {
if (e.target === panel) {
panel.remove();
}
});
}
function showMessage(text, type) {
const colors = {
success: '#4CAF50',