// ==UserScript==
// @name 易迅数据服务自动审批
// @namespace http://tampermonkey.net/
// @version 4.2
// @description 修复确定按钮点击失效问题,增加元素等待机制
// @author 刘运运
// @match *://*/partal/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
const TARGET_PATH = '/partal/#/layout/home/personal-center/myTodoList';
const NEW_TARGET_PATH = '/partal/#/layout/home/data-center/serviceMarket'; // 新增的目标路径
let panel = null; // 用于存储面板的DOM对象
let isRunning = false;
let clickTimer = null; // 用于防抖
// --- 1. 判断页面路径 ---
function isTargetPage() {
return window.location.href.includes(TARGET_PATH);
}
function isNewTargetPage() {
return window.location.href.includes(NEW_TARGET_PATH);
}
// --- 2. 创建并显示控制面板 (原有功能) ---
function showPanel() {
if (panel || !isTargetPage()) return;
panel = document.createElement('div');
panel.id = 'auto-task-panel';
panel.style.cssText = `position: fixed; bottom: 20px; right: 20px; width: 300px; background: #fff;
border: 1px solid #409EFF; border-radius: 8px; box-shadow: 0 4px 12px rgba(64,158,255,0.3);
z-index: 9999; padding: 15px; font-family: Arial, sans-serif;`;
panel.innerHTML = `
自动审批助手
`;
document.body.appendChild(panel);
log('✅ 脚本已就绪');
document.getElementById('startBtn').addEventListener('click', startProcess);
document.getElementById('stopBtn').addEventListener('click', stopProcess);
}
// --- 3. 隐藏并销毁控制面板 ---
function hidePanel() {
if (panel) {
if (isRunning) stopProcess();
panel.remove();
panel = null;
console.log('❌ 离开目标页面,脚本面板已隐藏');
}
}
// --- 4. 日志与工具函数 ---
function log(msg) {
const logBox = document.getElementById('logBox');
if (logBox) {
logBox.innerHTML += `[${new Date().toLocaleTimeString()}] ${msg}
`;
logBox.scrollTop = logBox.scrollHeight;
}
}
function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); }
// --- 5. 核心业务逻辑 (原有功能) ---
async function startProcess() {
if (isRunning) return;
isRunning = true;
document.getElementById('startBtn').disabled = true;
log('🚀 任务启动...');
while (isRunning) {
if (!isTargetPage()) {
stopProcess();
break;
}
// 阶段一:寻找弹窗中的“同意”按钮
const agreeBtn = Array.from(document.querySelectorAll('button, span'))
.find(el => el.innerText.trim() === '同意' && el.offsetWidth > 0);
if (agreeBtn) {
log('🔍 发现弹窗,点击同意...');
agreeBtn.click();
await sleep(2000);
continue;
}
// 阶段二:寻找主页面的“处理”按钮
const handleBtn = document.querySelector('i.handletable');
if (handleBtn) {
log('🔍 找到待处理项,点击...');
handleBtn.click();
await sleep(1000);
} else {
log('🏁 未找到任务,直接停止');
stopProcess();
break;
}
}
}
function stopProcess() {
isRunning = false;
const startBtn = document.getElementById('startBtn');
if (startBtn) startBtn.disabled = false;
log('🛑 任务已停止');
}
// --- 6. 新增功能:右上角“执行确定”按钮 ---
let externalBtn = null;
function createExternalButton() {
if (externalBtn || !isNewTargetPage()) return;
externalBtn = document.createElement('button');
externalBtn.id = 'external-confirm-btn';
// 样式:固定在右上角,高亮显示
externalBtn.style.cssText = `
position: fixed; top: 150px; right: 20px; z-index: 9999;
padding: 8px 15px; background: #409EFF; color: white;
border: none; border-radius: 4px; font-weight: bold;
box-shadow: 0 2px 10px rgba(0,0,0,0.2); cursor: pointer;
display: flex; align-items: center; gap: 5px;
`;
externalBtn.innerHTML = `✅ 执行确定`;
document.body.appendChild(externalBtn);
// 绑定点击事件
externalBtn.addEventListener('click', async () => {
log('👆 手动触发:开始寻找弹窗...');
externalBtn.disabled = true;
externalBtn.innerText = '⏳ 处理中...';
// 核心修复:等待弹窗出现 (最多等待 5 秒)
let confirmBtn = null;
let attempts = 0;
const maxAttempts = 50; // 50 * 100ms = 5000ms
while (attempts < maxAttempts) {
// 精准定位:查找包含文本“确定”的 button 元素
const buttons = document.querySelectorAll('button');
confirmBtn = Array.from(buttons).find(btn => btn.innerText.trim() === '确定');
if (confirmBtn) break;
await sleep(100);
attempts++;
}
if (confirmBtn) {
log('🔍 成功定位到“确定”按钮,正在点击...');
// 尝试多种方式点击以确保生效
confirmBtn.scrollIntoView({ behavior: 'smooth', block: 'center' });
await sleep(300); // 等待滚动到位
confirmBtn.click();
// 模拟鼠标事件 (针对某些框架如Vue/React需要)
['mousedown', 'mouseup', 'click'].forEach(eventType => {
const event = new MouseEvent(eventType, {
view: window,
bubbles: true,
cancelable: true
});
confirmBtn.dispatchEvent(event);
});
log('✅ 点击指令已发送');
} else {
log('❌ 错误:未找到“确定”按钮,请确保弹窗已打开');
}
// 恢复按钮状态
await sleep(1000);
externalBtn.disabled = false;
externalBtn.innerText = '✅ 执行确定';
});
}
function removeExternalButton() {
if (externalBtn) {
externalBtn.remove();
externalBtn = null;
console.log('❌ 离开服务市场页面,右上角按钮已销毁');
}
}
// --- 7. 初始化与 URL 监听 ---
if (isTargetPage()) showPanel();
if (isNewTargetPage()) createExternalButton();
const observer = new MutationObserver(() => {
// 逻辑 1:控制面板 (myTodoList)
const currentIsTarget = isTargetPage();
if (currentIsTarget && !panel) {
showPanel();
} else if (!currentIsTarget && panel) {
hidePanel();
}
// 逻辑 2:右上角按钮 (serviceMarket)
const currentIsNewTarget = isNewTargetPage();
if (currentIsNewTarget && !externalBtn) {
createExternalButton();
} else if (!currentIsNewTarget && externalBtn) {
removeExternalButton();
}
});
observer.observe(document.body, { childList: true, subtree: true });
})();