Greasy Fork is available in English.
支持拖拽移动、折叠、半透明的华医CME数据清理工具
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.greasyfork.icu/scripts/553000/1679785/%E5%8D%8E%E5%8C%BBCME%E6%95%B0%E6%8D%AE%E6%B8%85%E7%90%86%E5%B7%A5%E5%85%B7%EF%BC%88%E5%A2%9E%E5%BC%BA%E7%89%88%EF%BC%89.js
// ==UserScript==
// @name 华医CME数据清理工具(增强版)
// @namespace http://tampermonkey.net/
// @version 0.2
// @description 支持拖拽移动、折叠、半透明的华医CME数据清理工具
// @author 您的名字
// @match *://cme28.91huayi.com/*
// @grant GM_deleteValue
// @grant GM_getValue
// @grant GM_setValue
// ==/UserScript==
(function() {
'use strict';
// 全局状态:控制折叠和拖拽
let isCollapsed = false;
let isDragging = false;
let dragStartX = 0;
let dragStartY = 0;
// 创建增强版清理工具界面
function createCleanerUI() {
if (document.getElementById('cme-cleaner-container')) return;
// 1. 主容器(支持拖拽和半透明)
const container = document.createElement('div');
container.id = 'cme-cleaner-container';
container.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
z-index: 9999;
background: rgba(255,255,255,0.9); /* 初始半透明 */
backdrop-filter: blur(3px);
padding: 0;
border-radius: 8px;
box-shadow: 0 2px 15px rgba(0,0,0,0.15);
width: 300px;
font-family: Arial, sans-serif;
transition: all 0.3s ease;
cursor: move; /* 初始拖拽光标 */
`;
// 2. 标题栏(拖拽触发区 + 折叠按钮)
const header = document.createElement('div');
header.id = 'cme-cleaner-header';
header.style.cssText = `
padding: 10px 15px;
background: #4096ff;
color: white;
border-top-left-radius: 8px;
border-top-right-radius: 8px;
font-weight: bold;
display: flex;
justify-content: space-between;
align-items: center;
`;
header.textContent = '华医CME数据清理';
// 折叠/展开按钮
const toggleBtn = document.createElement('button');
toggleBtn.id = 'cme-cleaner-toggle';
toggleBtn.innerHTML = '−'; // 初始折叠符号
toggleBtn.style.cssText = `
background: transparent;
border: none;
color: white;
font-size: 18px;
cursor: pointer;
padding: 0 5px;
line-height: 1;
`;
header.appendChild(toggleBtn);
container.appendChild(header);
// 3. 内容区(可折叠)
const content = document.createElement('div');
content.id = 'cme-cleaner-content';
content.style.cssText = `
padding: 15px;
display: block; /* 初始展开 */
transition: all 0.3s ease;
`;
// 批量清理按钮
const clearAllBtn = document.createElement('button');
clearAllBtn.textContent = '清理所有数据';
clearAllBtn.style.cssText = `
width: 100%;
padding: 8px;
background: #dc3545;
color: white;
border: none;
border-radius: 4px;
cursor: pointer;
margin-bottom: 15px;
font-weight: bold;
transition: background 0.2s;
`;
clearAllBtn.addEventListener('click', clearAllData);
content.appendChild(clearAllBtn);
// 单独清理区域标题
const singleTitle = document.createElement('p');
singleTitle.textContent = '单独清理项:';
singleTitle.style.cssText = 'margin: 10px 0 5px; color: #666; font-size: 14px;';
content.appendChild(singleTitle);
// 数据项列表
const dataItems = [
{ id: 'courseList', type: 'GM', name: '课程列表' },
{ id: 'dept_id2', type: 'GM', name: '部门ID' },
{ id: 'title_id', type: 'GM', name: '标题ID' },
{ id: 'savedQuestions', type: 'GM', name: '保存的问题' },
{ id: 'currentCourseIndex', type: 'local', name: '当前课程索引' },
{ id: 'allCourseLinks', type: 'local', name: '所有课程链接' },
{ id: 'videolinks', type: 'local', name: '视频链接' },
{ id: 'examIndex', type: 'local', name: '考试索引' },
{ id: 'savedLoginName', type: 'local', name: '保存的登录名' }
];
// 创建单独清理按钮
dataItems.forEach(item => {
const itemDiv = document.createElement('div');
itemDiv.style.cssText = 'margin-bottom: 6px; display: flex; justify-content: space-between; align-items: center;';
const itemName = document.createElement('span');
itemName.textContent = item.name;
itemName.style.cssText = 'font-size: 13px;';
const itemBtn = document.createElement('button');
itemBtn.textContent = '清理';
itemBtn.style.cssText = `
padding: 3px 8px;
background: #6c757d;
color: white;
border: none;
border-radius: 3px;
cursor: pointer;
font-size: 12px;
transition: background 0.2s;
`;
itemBtn.addEventListener('click', () => clearSingleItem(item.id, item.type, item.name));
itemDiv.appendChild(itemName);
itemDiv.appendChild(itemBtn);
content.appendChild(itemDiv);
});
// 状态提示
const statusDiv = document.createElement('div');
statusDiv.id = 'cme-cleaner-status';
statusDiv.style.cssText = `
margin-top: 10px;
padding: 5px;
border-radius: 4px;
font-size: 12px;
display: none;
`;
content.appendChild(statusDiv);
container.appendChild(content);
// 4. 透明度调节(可选)
const opacityControl = document.createElement('div');
opacityControl.style.cssText = `
padding: 0 15px 10px;
display: flex;
align-items: center;
gap: 8px;
font-size: 12px;
color: #666;
`;
opacityControl.innerHTML = `
<span>透明度:</span>
<input type="range" min="50" max="100" value="90" id="cme-opacity-slider">
<span id="cme-opacity-value">90%</span>
`;
container.appendChild(opacityControl);
document.body.appendChild(container);
// 绑定核心交互事件
bindInteractions();
}
// 绑定拖拽、折叠、透明度调节事件
function bindInteractions() {
const container = document.getElementById('cme-cleaner-container');
const header = document.getElementById('cme-cleaner-header');
const content = document.getElementById('cme-cleaner-content');
const toggleBtn = document.getElementById('cme-cleaner-toggle');
const opacitySlider = document.getElementById('cme-opacity-slider');
const opacityValue = document.getElementById('cme-opacity-value');
// 1. 拖拽功能
header.addEventListener('mousedown', (e) => {
isDragging = true;
// 记录初始拖拽位置(鼠标相对于容器的偏移)
dragStartX = e.clientX - container.offsetLeft;
dragStartY = e.clientY - container.offsetTop;
container.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (e) => {
if (!isDragging) return;
// 计算新位置(避免鼠标超出窗口)
const newLeft = e.clientX - dragStartX;
const newTop = e.clientY - dragStartY;
// 限制在可视窗口内
const maxLeft = window.innerWidth - container.offsetWidth;
const maxTop = window.innerHeight - container.offsetHeight;
container.style.left = `${Math.max(0, Math.min(newLeft, maxLeft))}px`;
container.style.top = `${Math.max(0, Math.min(newTop, maxTop))}px`;
// 取消固定右定位(避免拖拽冲突)
container.style.right = 'auto';
});
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
container.style.cursor = 'move';
}
});
// 2. 折叠/展开功能
toggleBtn.addEventListener('click', () => {
isCollapsed = !isCollapsed;
if (isCollapsed) {
content.style.display = 'none';
opacitySlider.style.display = 'none'; // 折叠时隐藏透明度调节
opacityValue.style.display = 'none';
toggleBtn.innerHTML = '+'; // 展开符号
container.style.width = '180px'; // 缩小宽度
} else {
content.style.display = 'block';
opacitySlider.style.display = 'inline-block';
opacityValue.style.display = 'inline-block';
toggleBtn.innerHTML = '−'; // 折叠符号
container.style.width = '300px'; // 恢复宽度
}
});
// 3. 透明度调节
opacitySlider.addEventListener('input', (e) => {
const value = e.target.value;
opacityValue.textContent = `${value}%`;
container.style.background = `rgba(255,255,255,${value / 100})`;
});
// 4. 内容区点击取消拖拽光标(避免按钮hover异常)
content.addEventListener('mouseenter', () => {
if (!isDragging) container.style.cursor = 'default';
});
content.addEventListener('mouseleave', () => {
if (!isDragging) container.style.cursor = 'move';
});
}
// 显示操作状态提示
function showStatus(message, isError = false) {
const statusDiv = document.getElementById('cme-cleaner-status');
statusDiv.textContent = message;
statusDiv.style.display = 'block';
statusDiv.style.backgroundColor = isError ? 'rgba(248,215,218,0.9)' : 'rgba(212,237,218,0.9)';
statusDiv.style.color = isError ? '#721c24' : '#155724';
// 3秒后自动隐藏
setTimeout(() => statusDiv.style.display = 'none', 3000);
}
// 清理单个数据项
function clearSingleItem(id, type, name) {
try {
if (type === 'GM') {
typeof GM_deleteValue === 'function'
? (GM_deleteValue(id), showStatus(`已清理:${name}`))
: showStatus('GM_deleteValue函数不可用', true);
} else {
localStorage.removeItem(id);
showStatus(`已清理:${name}`);
}
} catch (e) {
showStatus(`清理失败:${e.message}`, true);
}
}
// 清理所有数据(带确认提示)
function clearAllData() {
if (!confirm('确定要清理所有数据吗?此操作不可恢复!')) return;
try {
// 清理GM存储
['courseList', 'dept_id2', 'title_id', 'savedQuestions'].forEach(id => {
typeof GM_deleteValue === 'function' && GM_deleteValue(id);
});
// 清理localStorage
['currentCourseIndex', 'allCourseLinks', 'videolinks', 'examIndex', 'savedLoginName'].forEach(id => {
localStorage.removeItem(id);
});
showStatus('所有数据已清理完成');
} catch (e) {
showStatus(`清理失败:${e.message}`, true);
}
}
// 页面加载完成后初始化
window.addEventListener('load', createCleanerUI);
})();