chatshare车辆跟踪器,让你更快找到新车

跟踪共享账号池中的新车辆并添加复制按钮,让你更快找到新车

当前为 2025-05-18 提交的版本,查看 最新版本

// ==UserScript==
// @name         chatshare车辆跟踪器,让你更快找到新车
// @namespace    http://tampermonkey.net/
// @version      1.3
// @description  跟踪共享账号池中的新车辆并添加复制按钮,让你更快找到新车
// @author       schweigen
// @match        https://chatshare.xyz/pastel/*
// @grant        GM_addStyle
// @grant        GM_setClipboard
// @license MIT
// ==/UserScript==

(function() {
    'use strict';

    // 添加CSS样式
    GM_addStyle(`
        #carTrackerPanel {
            position: fixed;
            top: 10px;
            left: 10px;
            background-color: white;
            border: 1px solid #ccc;
            border-radius: 5px;
            padding: 10px;
            z-index: 9999;
            max-height: 300px;
            overflow-y: auto;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
            transition: all 0.3s ease;
            font-family: Arial, sans-serif;
            font-size: 14px;
        }

        #carTrackerHeader {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 10px;
            border-bottom: 1px solid #eee;
            padding-bottom: 5px;
        }

        #carTrackerTitle {
            margin: 0;
            font-size: 16px;
            font-weight: bold;
            color: #333;
        }

        .carTrackerButton {
            padding: 5px 10px;
            border: none;
            border-radius: 3px;
            cursor: pointer;
            font-size: 12px;
            margin-right: 5px;
            margin-bottom: 5px;
        }

        #saveButton {
            background-color: #4CAF50;
            color: white;
        }

        #toggleListButton {
            background-color: #2196F3;
            color: white;
        }

        #addButton {
            background-color: #ff9800;
            color: white;
        }

        #togglePanelButton {
            border: none;
            background: none;
            cursor: pointer;
            font-size: 18px;
        }

        #carList {
            margin-top: 10px;
            margin-bottom: 10px;
            max-height: 150px;
            overflow-y: auto;
            display: none;
        }

        #carList ul {
            margin: 0;
            padding-left: 20px;
        }

        #addCarInput {
            width: 150px;
            padding: 5px;
            margin-right: 5px;
            border: 1px solid #ccc;
            border-radius: 3px;
        }

        #addCarForm {
            display: flex;
            margin-bottom: 10px;
            align-items: center;
        }

        .newCar {
            background-color: #ffd54f !important;
            border: 2px solid #ffc107 !important;
            animation: pulseBorder 1s infinite alternate !important;
        }

        @keyframes pulseBorder {
            from {
                box-shadow: 0 0 5px #ffc107;
            }
            to {
                box-shadow: 0 0 15px #ffc107;
            }
        }

        /* 复制按钮样式 */
        .copy-button {
            background-color: #1E90FF;
            color: white;
            border: none;
            border-radius: 3px;
            padding: 2px 5px;
            font-size: 10px;
            cursor: pointer;
            margin-left: 5px;
            vertical-align: middle;
            height: 22px;
            line-height: 18px;
        }

        .copy-button:hover {
            background-color: #0066CC;
        }

        .copy-success {
            background-color: #4CAF50;
        }

        /* 调整车名容器样式 */
        .state-info {
            display: flex !important;
            align-items: center !important;
            flex-wrap: wrap !important;
            justify-content: space-between !important;
        }

        .state-info p {
            margin-right: 5px !important;
        }

        /* 顶部通知样式 */
        #notificationToast {
            position: fixed;
            top: 20px;
            left: 50%;
            transform: translateX(-50%);
            background-color: rgba(0, 0, 0, 0.7);
            color: white;
            padding: 10px 20px;
            border-radius: 5px;
            z-index: 10000;
            font-size: 14px;
            opacity: 0;
            transition: opacity 0.3s ease;
        }

        .notification-show {
            opacity: 1 !important;
        }
    `);

    // 全局变量
    let isInitialized = false;
    let checkInterval = null;
    let urlCheckInterval = null;
    let lastUrl = '';

    // 初始化函数
    function init() {
        console.log('[车辆跟踪器] 初始化中...');

        // 创建通知元素
        if (!document.getElementById('notificationToast')) {
            const toast = document.createElement('div');
            toast.id = 'notificationToast';
            document.body.appendChild(toast);
        }

        // 保存当前URL
        lastUrl = location.href;

        // 立即检查一次URL
        checkUrlAndInitialize();

        // 设置URL定期检查,每500毫秒检查一次URL变化
        urlCheckInterval = setInterval(function() {
            // 只有当URL发生变化时才检查
            if (lastUrl !== location.href) {
                console.log('[车辆跟踪器] 检测到URL变化:', lastUrl, '->', location.href);
                lastUrl = location.href;
                checkUrlAndInitialize();
            }
        }, 500);

        // 添加常规的hashchange监听
        window.addEventListener('hashchange', function() {
            console.log('[车辆跟踪器] hashchange事件触发');
            checkUrlAndInitialize();
        });

        // 添加popstate监听
        window.addEventListener('popstate', function() {
            console.log('[车辆跟踪器] popstate事件触发');
            checkUrlAndInitialize();
        });

        console.log('[车辆跟踪器] 初始化完成,开始监听URL变化');
    }

    // 检查URL并根据需要初始化功能
    function checkUrlAndInitialize() {
        const isCarListPage = location.hash.startsWith('#/carlist');
        console.log('[车辆跟踪器] 检查URL:', location.href, '是否是车辆列表页面:', isCarListPage);

        if (isCarListPage && !isInitialized) {
            console.log('[车辆跟踪器] 检测到车辆列表页面,开始启动跟踪器');
            // 启动跟踪器前等待DOM加载
            setTimeout(startTracker, 1000);
        } else if (!isCarListPage && isInitialized) {
            console.log('[车辆跟踪器] 离开车辆列表页面,停止跟踪器');
            // 停止跟踪器
            stopTracker();
        }
    }

    // 启动跟踪器
    function startTracker() {
        try {
            // 创建并添加面板到页面
            createPanel();

            // 检查新车并高亮显示
            checkForNewCars();

            // 为所有车名添加复制按钮
            addCopyButtons();

            // 定期检查新的车辆元素
            checkInterval = setInterval(addCopyButtons, 2000);

            isInitialized = true;

            showNotification('车辆跟踪器已启动');
        } catch (err) {
            console.error('车辆跟踪器启动失败:', err);
        }
    }

    // 停止跟踪器
    function stopTracker() {
        if (checkInterval) {
            clearInterval(checkInterval);
            checkInterval = null;
        }

        const panel = document.getElementById('carTrackerPanel');
        if (panel) panel.remove();

        isInitialized = false;
    }

    // 创建面板
    function createPanel() {
        // 检查面板是否已存在
        if (document.getElementById('carTrackerPanel')) return;

        // 创建面板容器
        const panel = document.createElement('div');
        panel.id = 'carTrackerPanel';

        // 创建标题栏
        const header = document.createElement('div');
        header.id = 'carTrackerHeader';

        const title = document.createElement('h3');
        title.id = 'carTrackerTitle';
        title.textContent = '车辆跟踪器';

        const toggleButton = document.createElement('button');
        toggleButton.id = 'togglePanelButton';
        toggleButton.textContent = '−';

        header.appendChild(title);
        header.appendChild(toggleButton);

        // 创建添加单个车辆的表单
        const addCarForm = document.createElement('div');
        addCarForm.id = 'addCarForm';

        const addCarInput = document.createElement('input');
        addCarInput.id = 'addCarInput';
        addCarInput.type = 'text';
        addCarInput.placeholder = '输入车辆名称';

        const addButton = document.createElement('button');
        addButton.id = 'addButton';
        addButton.className = 'carTrackerButton';
        addButton.textContent = '添加车辆';

        addCarForm.appendChild(addCarInput);
        addCarForm.appendChild(addButton);

        // 创建内容区
        const content = document.createElement('div');
        content.id = 'carTrackerContent';

        // 创建统计部分
        const statsSection = document.createElement('div');
        statsSection.id = 'carStats';

        // 从localStorage加载车辆
        const savedCars = getSavedCars();
        const totalCars = document.querySelectorAll('.chatgpt').length;
        const newCars = countNewCars(savedCars);

        statsSection.innerHTML = `
            <p><strong>统计信息:</strong></p>
            <ul>
                <li>已保存车辆: ${savedCars.length}</li>
                <li>当前车辆: ${totalCars}</li>
                <li>新车辆: ${newCars} (<span style="color: #ffc107;">以金色高亮显示</span>)</li>
            </ul>
        `;

        // 创建按钮组
        const buttonGroup = document.createElement('div');
        buttonGroup.id = 'carTrackerButtons';

        const toggleListButton = document.createElement('button');
        toggleListButton.id = 'toggleListButton';
        toggleListButton.className = 'carTrackerButton';
        toggleListButton.textContent = '显示已保存车辆';

        const saveButton = document.createElement('button');
        saveButton.id = 'saveButton';
        saveButton.className = 'carTrackerButton';
        saveButton.textContent = '保存当前车辆';

        buttonGroup.appendChild(toggleListButton);
        buttonGroup.appendChild(saveButton);

        // 创建车辆列表(初始隐藏)
        const carList = document.createElement('div');
        carList.id = 'carList';

        if (savedCars.length > 0) {
            carList.innerHTML = '<p><strong>已保存车辆:</strong></p>';
            const list = document.createElement('ul');

            savedCars.forEach(car => {
                const item = document.createElement('li');
                item.textContent = car;
                list.appendChild(item);
            });

            carList.appendChild(list);
        } else {
            carList.innerHTML = '<p>尚未保存任何车辆。</p>';
        }

        // 添加事件监听器
        toggleButton.addEventListener('click', function() {
            if (content.style.display === 'none') {
                content.style.display = 'block';
                toggleButton.textContent = '−';
            } else {
                content.style.display = 'none';
                toggleButton.textContent = '+';
            }
        });

        toggleListButton.addEventListener('click', function() {
            if (carList.style.display === 'none') {
                carList.style.display = 'block';
                toggleListButton.textContent = '隐藏已保存车辆';
            } else {
                carList.style.display = 'none';
                toggleListButton.textContent = '显示已保存车辆';
            }
        });

        saveButton.addEventListener('click', saveCurrentCars);

        // 添加单个车辆的事件处理
        addButton.addEventListener('click', function() {
            addSingleCar();
        });

        addCarInput.addEventListener('keypress', function(e) {
            if (e.key === 'Enter') {
                e.preventDefault();
                addSingleCar();
            }
        });

        // 组装面板
        content.appendChild(statsSection);
        content.appendChild(buttonGroup);
        content.appendChild(carList);

        panel.appendChild(header);
        panel.appendChild(addCarForm);
        panel.appendChild(content);

        // 将面板添加到页面
        document.body.appendChild(panel);
    }

    // 为所有车名添加复制按钮
    function addCopyButtons() {
        const carNameElements = document.querySelectorAll('.state-info p');

        carNameElements.forEach(nameElement => {
            // 检查是否已经添加了复制按钮
            if (nameElement.parentNode.querySelector('.copy-button')) {
                return; // 已经有按钮了,跳过
            }

            const carName = nameElement.textContent.trim();
            const copyButton = document.createElement('button');
            copyButton.textContent = '复制';
            copyButton.className = 'copy-button';
            copyButton.title = '复制车名到剪贴板';

            copyButton.addEventListener('click', function(event) {
                event.stopPropagation(); // 阻止事件冒泡,避免触发车辆的点击事件

                // 复制到剪贴板
                GM_setClipboard(carName);

                // 显示复制成功的视觉反馈
                copyButton.textContent = '已复制';
                copyButton.classList.add('copy-success');

                // 2秒后恢复原样
                setTimeout(function() {
                    copyButton.textContent = '复制';
                    copyButton.classList.remove('copy-success');
                }, 2000);
            });

            // 将按钮添加到车名后面
            nameElement.parentNode.appendChild(copyButton);
        });
    }

    // 检查新车并高亮显示
    function checkForNewCars() {
        const savedCars = getSavedCars();

        // 获取页面上所有车辆元素
        const carElements = document.querySelectorAll('.chatgpt');

        carElements.forEach(element => {
            const nameElement = element.querySelector('.state-info p');
            if (nameElement) {
                const carName = nameElement.textContent.trim();

                // 检查这个车是否已保存
                if (!savedCars.includes(carName)) {
                    // 高亮显示为新车
                    element.classList.add('newCar');
                }
            }
        });
    }

    // 添加单个车辆的功能
    function addSingleCar() {
        const input = document.getElementById('addCarInput');
        const carName = input.value.trim();

        if (carName) {
            // 获取现有的保存车辆
            const savedCars = getSavedCars();

            // 检查是否已经存在
            if (!savedCars.includes(carName)) {
                // 添加到保存列表
                savedCars.push(carName);
                localStorage.setItem('savedCars', JSON.stringify(savedCars));

                // 更新UI
                updateCarList(savedCars);
                updateStats();

                // 查找并移除高亮
                const carElements = document.querySelectorAll('.chatgpt');
                carElements.forEach(element => {
                    const nameElement = element.querySelector('.state-info p');
                    if (nameElement && nameElement.textContent.trim() === carName) {
                        element.classList.remove('newCar');
                    }
                });

                // 清空输入框
                input.value = '';

                // 显示通知
                showNotification(`已添加车辆: ${carName}`);
            } else {
                showNotification(`车辆 ${carName} 已在保存列表中!`);
            }
        } else {
            showNotification('请输入车辆名称!');
        }
    }

    // 保存当前所有车辆
    function saveCurrentCars() {
        // 清除之前保存的车辆
        localStorage.removeItem('savedCars');

        // 获取页面上所有车辆元素
        const carElements = document.querySelectorAll('.chatgpt');
        const currentCars = [];

        carElements.forEach(element => {
            const nameElement = element.querySelector('.state-info p');
            if (nameElement) {
                const carName = nameElement.textContent.trim();
                currentCars.push(carName);

                // 移除高亮
                element.classList.remove('newCar');
            }
        });

        // 保存到localStorage
        localStorage.setItem('savedCars', JSON.stringify(currentCars));

        // 更新UI
        updateCarList(currentCars);
        updateStats();

        // 显示通知
        showNotification('当前车辆已成功保存!');
    }

    // 更新车辆列表UI
    function updateCarList(cars) {
        const carList = document.getElementById('carList');
        if (carList) {
            if (cars.length > 0) {
                carList.innerHTML = '<p><strong>已保存车辆:</strong></p>';
                const list = document.createElement('ul');

                cars.forEach(car => {
                    const item = document.createElement('li');
                    item.textContent = car;
                    list.appendChild(item);
                });

                carList.appendChild(list);
            } else {
                carList.innerHTML = '<p>尚未保存任何车辆。</p>';
            }
        }
    }

    // 更新统计信息
    function updateStats() {
        const statsSection = document.getElementById('carStats');
        if (statsSection) {
            const savedCars = getSavedCars();
            const totalCars = document.querySelectorAll('.chatgpt').length;
            const newCars = countNewCars(savedCars);

            statsSection.innerHTML = `
                <p><strong>统计信息:</strong></p>
                <ul>
                    <li>已保存车辆: ${savedCars.length}</li>
                    <li>当前车辆: ${totalCars}</li>
                    <li>新车辆: ${newCars} (<span style="color: #ffc107;">以金色高亮显示</span>)</li>
                </ul>
            `;
        }
    }

    // 从localStorage获取保存的车辆
    function getSavedCars() {
        const cars = localStorage.getItem('savedCars');
        return cars ? JSON.parse(cars) : [];
    }

    // 计算新车数量
    function countNewCars(savedCars) {
        let count = 0;
        const carElements = document.querySelectorAll('.chatgpt');

        carElements.forEach(element => {
            const nameElement = element.querySelector('.state-info p');
            if (nameElement) {
                const carName = nameElement.textContent.trim();
                if (!savedCars.includes(carName)) {
                    count++;
                }
            }
        });

        return count;
    }

    // 显示通知
    function showNotification(message, duration = 3000) {
        const toast = document.getElementById('notificationToast');
        if (toast) {
            toast.textContent = message;
            toast.classList.add('notification-show');

            setTimeout(() => {
                toast.classList.remove('notification-show');
            }, duration);
        }
    }

    // 启动脚本
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', init);
    } else {
        init();
    }

})();