// ==UserScript== // @name TC脚本 // @namespace http://tampermonkey.net/ // @version 111 // @description 自动跟进系统 - 简化版 // @author You // @match http://call.changmujiayu.cn/web/2024/page/h5_tc/* // @match https://call.changmujiayu.cn/web/2024/page/h5_tc/* // @grant none // ==/UserScript== (function() { 'use strict'; console.log('脚本开始执行...'); // 立即拦截所有网页弹窗 (function() { console.log('设置弹窗拦截...'); // 保存原始函数 window._originalAlert = window.alert; window._originalConfirm = window.confirm; window._originalPrompt = window.prompt; // 添加错误处理,防止网页错误影响脚本 window.addEventListener('error', function(e) { if (e.filename && e.filename.includes('high_seas_list')) { console.log('忽略网页错误:', e.message); e.preventDefault(); } }); // 重写弹窗函数 window.alert = function(msg) { console.log('拦截alert:', msg); // 检测跟进失败的alert,触发自动刷新 if (msg && msg.includes('跟进失败')) { setTimeout(startAutoRefresh, 500); } return; }; window.confirm = function(msg) { console.log('拦截confirm:', msg); return true; }; window.prompt = function(msg, def) { console.log('拦截prompt:', msg); return def || ''; }; console.log('弹窗拦截已设置'); })(); // 简单提示 function showToast(msg, type = 'info') { const toast = document.createElement('div'); toast.textContent = msg; toast.style.cssText = ` position: fixed; top: 20px; right: 20px; padding: 12px 24px; background: ${type === 'error' ? '#ff4444' : '#4CAF50'}; color: white; border-radius: 4px; box-shadow: 0 2px 4px rgba(0,0,0,0.2); z-index: 99999; `; document.body.appendChild(toast); setTimeout(() => toast.remove(), 1000); } // 等待元素出现 function waitForElement(selector, timeout = 2000) { return new Promise((resolve) => { const start = Date.now(); function check() { const el = document.querySelector(selector); if (el) { resolve(el); return; } if (Date.now() - start < timeout) { setTimeout(check, 100); } else { resolve(null); } } check(); }); } // 主函数 async function main() { console.log('开始主流程...'); try { // 1. 等待关键元素 const date1 = await waitForElement('#date1'); const date2 = await waitForElement('#date2'); const pkey = await waitForElement('#pkey_id'); const hasName = await waitForElement('#hasName'); if (!date1 || !date2 || !pkey || !hasName) { console.log('关键元素未找到'); return; } console.log('关键元素已找到'); // 2. 设置基础筛选条件 const today = new Date(); const dateStr = today.toISOString().split('T')[0]; date1.value = dateStr; date2.value = dateStr; hasName.value = ''; // 取消姓名筛选 pkey.value = '4'; // YXH-D平台 // 触发事件 [date1, date2, hasName, pkey].forEach(el => { el.dispatchEvent(new Event('change', { bubbles: true })); el.dispatchEvent(new Event('input', { bubbles: true })); }); console.log('基础筛选条件已设置'); // 3. 等待渠道下拉框更新(平台变更后) await new Promise(resolve => setTimeout(resolve, 500)); // 4. 设置渠道 const ckey = document.getElementById('ckey_id'); if (ckey) { const savedChannel = localStorage.getItem('weiyong222_selected_channel'); if (savedChannel !== null) { // 检查渠道是否可用 let available = false; for (let i = 0; i < ckey.options.length; i++) { if (ckey.options[i].value === savedChannel) { available = true; break; } } if (available || savedChannel === '') { ckey.value = savedChannel; ckey.dispatchEvent(new Event('change', { bubbles: true })); console.log('渠道已设置:', savedChannel); } } // 添加下拉式渠道选择器 addChannelSelector(); } // 5. 添加开始抢按钮 addStartGrabButton(); // 6. 检查是否需要自动开始 const autoStart = localStorage.getItem('weiyong222_auto_start') === 'true'; if (autoStart) { console.log('检测到自动开始设置,准备自动执行...'); await new Promise(resolve => setTimeout(resolve, 1000)); startGrabProcess(); } console.log('主流程完成'); } catch (error) { console.error('执行出错:', error); showToast('脚本执行出错', 'error'); } } // 自动跟进功能 function startAutoFollow() { console.log('开始自动跟进...'); // 检查客户列表 checkCustomers(); // 每500毫秒检查一次(降低频率避免刷新太快) setInterval(() => { checkCustomers(); }, 500); console.log('自动跟进循环已启动,每500ms检查一次'); } function checkCustomers() { const rows = document.querySelectorAll('#load tr'); console.log('检查客户列表,找到行数:', rows.length); let followed = 0; let hasNewCustomers = false; rows.forEach((row, index) => { const cells = row.querySelectorAll('td'); if (cells.length >= 5) { const timeCell = cells[4]; // 第5列是注册时间 const timeText = timeCell.textContent.trim(); console.log('第' + (index + 1) + '行客户时间:', timeText); const customerTime = parseTime(timeText); const now = new Date(); const fiveMinsAgo = new Date(now.getTime() - 3 * 60 * 1000); // 改为3分钟,增加时间窗口 console.log('时间对比: 客户时间=' + customerTime + ', 5分钟前=' + fiveMinsAgo + ', 是否新客户=' + (customerTime && customerTime > fiveMinsAgo)); if (customerTime && customerTime > fiveMinsAgo) { hasNewCustomers = true; console.log('发现新客户:', timeText); const lastCell = cells[cells.length - 1]; // 最后一列是操作列 const followBtn = lastCell.querySelector('a'); if (followBtn && followBtn.textContent.includes('开始跟进')) { console.log('找到跟进按钮,准备点击'); console.log('按钮onclick:', followBtn.getAttribute('onclick')); followBtn.click(); followed++; console.log('✅ 跟进客户:', timeText); } else { console.log('❌ 未找到跟进按钮或按钮文本不匹配'); console.log('跟进按钮:', followBtn); console.log('按钮文本:', followBtn ? followBtn.textContent : 'null'); console.log('按钮onclick:', followBtn ? followBtn.getAttribute('onclick') : 'null'); } } } }); console.log('检查结果: 总行数=' + rows.length + ', 新客户=' + hasNewCustomers + ', 成功跟进=' + followed); if (followed > 0) { // 跟进成功,不显示弹窗 console.log('跟进 ' + followed + ' 个客户'); } else if (rows.length === 0) { // 没有客户,自动点击筛选刷新 console.log('🔄 没有客户,自动点击筛选刷新'); const filterBtn = document.querySelector('.btn-primary.btn-block'); if (filterBtn && filterBtn.textContent.includes('筛选')) { filterBtn.click(); showToast('没有客户,自动刷新'); console.log('✅ 已点击筛选按钮'); } else { console.log('❌ 未找到筛选按钮'); } } else if (rows.length > 0 && !hasNewCustomers) { // 有客户但都过期了,自动点击筛选刷新 console.log('🔄 客户数据过期,自动点击筛选刷新'); const filterBtn = document.querySelector('.btn-primary.btn-block'); if (filterBtn && filterBtn.textContent.includes('筛选')) { filterBtn.click(); showToast('客户数据过期,自动刷新'); console.log('✅ 已点击筛选按钮'); } else { console.log('❌ 未找到筛选按钮'); } } } function parseTime(timeStr) { if (!timeStr) return null; try { // 尝试解析时间格式 const match = timeStr.match(/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/); if (match) { return new Date(match[1], match[2]-1, match[3], match[4], match[5], match[6]); } const match2 = timeStr.match(/(\d{4})-(\d{2})-(\d{2})/); if (match2) { return new Date(match2[1], match2[2]-1, match2[3]); } } catch(e) { console.log('时间解析错误:', e); } return null; } // 自动刷新功能 let refreshTimer = null; function startAutoRefresh() { if (refreshTimer) return; refreshTimer = setInterval(() => { const btn = document.querySelector('.btn-primary.btn-block'); if (btn && btn.textContent.includes('筛选')) { btn.click(); } }, 1000); } // 添加开始抢按钮 function addStartGrabButton() { if (document.querySelector('#start-grab-container')) return; const container = document.querySelector('.row .col-xl-1.col-md-6'); if (!container) return; // 创建按钮容器 const buttonContainer = document.createElement('div'); buttonContainer.id = 'start-grab-container'; buttonContainer.style.cssText = 'margin-top: 10px; display: flex; gap: 10px; align-items: center;'; // 创建开始抢按钮 const startGrabBtn = document.createElement('button'); startGrabBtn.id = 'start-grab-btn'; startGrabBtn.type = 'button'; startGrabBtn.className = 'btn btn-primary btn-block'; startGrabBtn.innerHTML = '开始抢'; startGrabBtn.style.cssText = 'padding: 8px 12px;'; // 创建自动开始复选框 const autoStartContainer = document.createElement('div'); autoStartContainer.style.cssText = 'display: flex; align-items: center; gap: 5px;'; const autoStartCheckbox = document.createElement('input'); autoStartCheckbox.id = 'auto-start-checkbox'; autoStartCheckbox.type = 'checkbox'; autoStartCheckbox.style.cssText = 'width: 16px; height: 16px;'; const autoStartLabel = document.createElement('label'); autoStartLabel.htmlFor = 'auto-start-checkbox'; autoStartLabel.textContent = '下次自动开始'; autoStartLabel.style.cssText = 'font-size: 14px; color: #666; cursor: pointer;'; // 设置复选框状态 const autoStart = localStorage.getItem('weiyong222_auto_start') === 'true'; autoStartCheckbox.checked = autoStart; // 按钮点击事件 startGrabBtn.onclick = function() { startGrabProcess(); }; // 复选框变化事件 autoStartCheckbox.onchange = function() { localStorage.setItem('weiyong222_auto_start', this.checked); showToast(this.checked ? '已设置下次自动开始' : '已取消自动开始', 'info'); }; // 组装元素 autoStartContainer.appendChild(autoStartCheckbox); autoStartContainer.appendChild(autoStartLabel); buttonContainer.appendChild(startGrabBtn); buttonContainer.appendChild(autoStartContainer); // 添加到筛选按钮旁边 container.parentNode.insertBefore(buttonContainer, container.nextSibling); console.log('开始抢按钮已添加'); } // 开始抢流程 async function startGrabProcess() { const startBtn = document.getElementById('start-grab-btn'); if (!startBtn) return; // 禁用按钮,防止重复点击 startBtn.disabled = true; startBtn.innerHTML = '抢占中...'; startBtn.className = 'btn btn-secondary btn-block'; showToast('开始抢占客户...', 'info'); console.log('开始执行抢占流程'); try { // 执行筛选 await new Promise(resolve => setTimeout(resolve, 500)); const filterBtn = document.querySelector('.btn-primary.btn-block'); if (filterBtn && filterBtn.textContent.includes('筛选')) { filterBtn.click(); showToast('筛选完成,开始自动跟进'); console.log('筛选按钮已点击'); // 开始自动跟进 setTimeout(() => { startAutoFollow(); // 更新按钮状态 startBtn.innerHTML = '抢占中'; startBtn.className = 'btn btn-success btn-block'; showToast('自动跟进已启动', 'success'); }, 700); } else { throw new Error('未找到筛选按钮'); } } catch (error) { console.error('抢占流程出错:', error); showToast('抢占失败: ' + error.message, 'error'); // 恢复按钮状态 startBtn.disabled = false; startBtn.innerHTML = '开始抢'; startBtn.className = 'btn btn-primary btn-block'; } } // 添加下拉式渠道选择器 function addChannelSelector() { if (document.querySelector('#channel-selector-container')) return; const container = document.querySelector('.row .col-xl-1.col-md-6'); if (!container) return; // 创建选择器容器 const selectorContainer = document.createElement('div'); selectorContainer.id = 'channel-selector-container'; selectorContainer.style.cssText = 'margin-top: 10px;'; // 创建标签 const label = document.createElement('label'); label.textContent = '快速选择渠道:'; label.style.cssText = 'display: block; margin-bottom: 5px; font-size: 14px; color: #666;'; // 创建下拉选择框 const channelSelect = document.createElement('select'); channelSelect.id = 'quick-channel-select'; channelSelect.className = 'form-control'; channelSelect.style.cssText = 'width: 100%; padding: 8px; border: 1px solid #ddd; border-radius: 4px;'; // 添加默认选项 const defaultOption = document.createElement('option'); defaultOption.value = ''; defaultOption.textContent = '请选择渠道...'; channelSelect.appendChild(defaultOption); // 动态获取当前可用的渠道选项 const ckey = document.getElementById('ckey_id'); if (ckey) { // 添加"全部渠道"选项(清空渠道筛选) const allChannelOption = document.createElement('option'); allChannelOption.value = 'all'; allChannelOption.textContent = '全部渠道'; channelSelect.appendChild(allChannelOption); // 添加其他渠道选项 for (let i = 1; i < ckey.options.length; i++) { const option = ckey.options[i]; if (option.value && option.text) { const newOption = document.createElement('option'); newOption.value = option.value; newOption.textContent = option.text; channelSelect.appendChild(newOption); } } } // 添加选择事件监听器 channelSelect.addEventListener('change', function() { const selectedValue = this.value; const selectedText = this.options[this.selectedIndex].text; if (selectedValue === 'all') { // 选择"全部渠道":清空渠道筛选 selectAllChannels(); } else if (selectedValue) { // 选择具体渠道 selectChannelByValue(selectedValue, selectedText); } }); // 添加到容器 selectorContainer.appendChild(label); selectorContainer.appendChild(channelSelect); // 添加到筛选按钮旁边 container.parentNode.insertBefore(selectorContainer, container.nextSibling); console.log('下拉式渠道选择器已添加'); } // 选择全部渠道(清空渠道筛选) function selectAllChannels() { const ckey = document.getElementById('ckey_id'); if (!ckey) { showToast('渠道选择框未找到', 'error'); return; } // 设置为空值(全部渠道) ckey.value = ''; ckey.dispatchEvent(new Event('change', { bubbles: true })); // 保存渠道选择到本地存储 localStorage.setItem('weiyong222_selected_channel', ''); // 重新执行筛选 setTimeout(() => { const filterBtn = document.querySelector('.btn-primary.btn-block'); if (filterBtn && filterBtn.textContent.includes('筛选')) { filterBtn.click(); showToast('已选择全部渠道(不筛选)', 'info'); } }, 500); } // 根据值选择渠道 function selectChannelByValue(channelValue, channelText) { const ckey = document.getElementById('ckey_id'); if (!ckey) { showToast('渠道选择框未找到', 'error'); return; } // 设置渠道值 ckey.value = channelValue; ckey.dispatchEvent(new Event('change', { bubbles: true })); // 保存渠道选择到本地存储 localStorage.setItem('weiyong222_selected_channel', channelValue); // 重新执行筛选 setTimeout(() => { const filterBtn = document.querySelector('.btn-primary.btn-block'); if (filterBtn && filterBtn.textContent.includes('筛选')) { filterBtn.click(); showToast(`已选择渠道: ${channelText}`, 'info'); } }, 500); } // 启动 if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', main); } else { setTimeout(main, 100); } })();