您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
2024-8-13更新,美化显示各模型总计调用次数和当天各自模型调用次数,可下载一天中不同时间段调用模型次数历史纪录。右键面板实时显示当天调用情况。
当前为
// ==UserScript== // @name ChatGPT模型调用计数器 // @namespace http://tampermonkey.net/ // @version 1.9 // @description 2024-8-13更新,美化显示各模型总计调用次数和当天各自模型调用次数,可下载一天中不同时间段调用模型次数历史纪录。右键面板实时显示当天调用情况。 // @author 狐狸的狐狸画 // @match https://chatgpt.com/* // @grant none // @license MIT // ==/UserScript== (function() { 'use strict'; // 定义模型对应的SVG图标 const modelIcons = { 'gpt-4o': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M19.92.897a.447.447 0 0 0-.89-.001c-.12 1.051-.433 1.773-.922 2.262-.49.49-1.21.801-2.262.923a.447.447 0 0 0 0 .888c1.035.117 1.772.43 2.274.922.499.49.817 1.21.91 2.251a.447.447 0 0 0 .89 0c.09-1.024.407-1.76.91-2.263.502-.502 1.238-.82 2.261-.908a.447.447 0 0 0 .001-.891c-1.04-.093-1.76-.411-2.25-.91-.493-.502-.806-1.24-.923-2.273ZM11.993 3.82a1.15 1.15 0 0 0-2.285-.002c-.312 2.704-1.115 4.559-2.373 5.817-1.258 1.258-3.113 2.06-5.817 2.373a.15 1.15 0 0 0 .003 2.285c2.658.3 4.555 1.104 5.845 2.37 1.283 1.26 2.1 3.112 2.338 5.789a.15 1.15 0 0 0 2.292-.003c.227-2.631 1.045-4.525 2.336-5.817 1.292-1.291 3.186-2.109 5.817-2.336a1.15 1.15 0 0 0 .003-2.291c-2.677-.238-4.529-1.056-5.789-2.34-1.266-1.29-2.07-3.186-2.37-5.844Z"></path></svg>`, 'gpt-4': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" d="M12.001 1.75c.496 0 .913.373.969.866.306 2.705 1.126 4.66 2.44 6 1.31 1.333 3.223 2.17 5.95 2.412a.976.976 0 0 1-.002 1.945c-2.682.232-4.637 1.067-5.977 2.408-1.34 1.34-2.176 3.295-2.408 5.977a.976.976 0 0 1-1.945.002c-.243-2.727-1.08-4.64-2.412-5.95-1.34-1.314-3.295-2.134-6-2.44a.976.976 0 0 1-.002-1.94c2.75-.317 4.665-1.137 5.972-2.444 1.307-1.307 2.127-3.221 2.444-5.972a.976.976 0 0 1 .971-.864Z"></path></svg>`, 'gpt-4o-mini': `<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" fill="none" viewBox="0 0 24 24"><path fill="currentColor" fill-rule="evenodd" d="M12.566 2.11c1.003-1.188 2.93-.252 2.615 1.271L14.227 8h5.697c1.276 0 1.97 1.492 1.146 2.467L11.434 21.89c-1.003 1.19-2.93.253-2.615-1.27L9.772 16H4.076c-1.276 0-1.97-1.492-1.147-2.467L12.565 2.11Z" clip-rule="evenodd"></path></svg>`, }; // 拦截fetch请求以监控模型调用 const originalFetch = window.fetch; window.fetch = function(url, options) { // 检查请求是否是对话请求并解析其请求体 if (url.includes("/backend-api/conversation") && options && options.method === "POST") { try { const body = JSON.parse(options.body); if (body.model) { updateModelCount(body.model); // 更新模型调用计数 } } catch (e) { console.error('解析请求体失败:', e); } } return originalFetch.apply(this, arguments); }; // 更新模型调用计数 function updateModelCount(model) { console.log(`模型调用: ${model}`); // 打印模型名称 const modelCountKey = 'model_counts'; // 本地存储键 const counts = JSON.parse(localStorage.getItem(modelCountKey) || '{}'); counts[model] = (counts[model] || 0) + 1; // 更新计数 localStorage.setItem(modelCountKey, JSON.stringify(counts)); updateHourlyCounts(model); // 更新每小时计数 displayCounts(); // 更新显示 } // 更新每小时计数 function updateHourlyCounts(model) { const date = new Date(); const hours = date.getHours(); const dayKey = date.toISOString().split('T')[0]; // YYYY-MM-DD 格式 const hourlyCountKey = `hourly_counts_${dayKey}`; const hourlyCounts = JSON.parse(localStorage.getItem(hourlyCountKey) || '{}'); if (!hourlyCounts[hours]) { hourlyCounts[hours] = {}; } hourlyCounts[hours][model] = (hourlyCounts[hours][model] || 0) + 1; localStorage.setItem(hourlyCountKey, JSON.stringify(hourlyCounts)); } // 获取今天每个模型的调用次数 function getTodayCounts() { const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD 格式 const hourlyCountKey = `hourly_counts_${date}`; const hourlyCounts = JSON.parse(localStorage.getItem(hourlyCountKey) || '{}'); const todayCounts = {}; for (let hour in hourlyCounts) { for (let model in hourlyCounts[hour]) { todayCounts[model] = (todayCounts[model] || 0) + hourlyCounts[hour][model]; } } return todayCounts; } // 保存数据到文件 function saveDataToFile() { const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD 格式 const modelCountKey = 'model_counts'; const hourlyCountKey = `hourly_counts_${date}`; const totalCounts = JSON.parse(localStorage.getItem(modelCountKey) || '{}'); const hourlyCounts = JSON.parse(localStorage.getItem(hourlyCountKey) || '{}'); const todayCounts = getTodayCounts(); // 准备保存的数据 const data = { total: totalCounts, // 总调用次数 hourly: hourlyCounts, // 每小时调用次数 today: todayCounts // 当天每个模型的调用次数 }; // 创建并下载JSON文件 const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' }); const url = URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = `model_usage_${date}.json`; // 文件命名 a.style.display = 'none'; document.body.appendChild(a); a.click(); document.body.removeChild(a); URL.revokeObjectURL(url); } // 定时每小时保存数据 function scheduleHourlySave() { const now = new Date(); const delay = (60 - now.getMinutes()) * 60 * 1000; // 距离下一个小时的延迟时间 setTimeout(() => { saveDataToFile(); setInterval(saveDataToFile, 60 * 60 * 1000); // 每小时保存一次 }, delay); } // 显示计数 function displayCounts() { const modelCountKey = 'model_counts'; const counts = JSON.parse(localStorage.getItem(modelCountKey) || '{}'); let displayText = ''; for (let model in counts) { const icon = modelIcons[model] || '❓'; // 默认图标 displayText += `<div style="display: flex; align-items: center; margin-right: 10px;">${icon} ${counts[model]}</div>`; } let displayDiv = document.getElementById('model-count-display'); if (!displayDiv) { displayDiv = document.createElement('div'); displayDiv.id = 'model-count-display'; Object.assign(displayDiv.style, { display: 'flex', position: 'fixed', top: '5px', left: '450px', backgroundColor: 'rgba(0,0,0,0)', color: 'rgba(66,66,66,1)', padding: '10px', borderRadius: '5px', zIndex: '1000', fontSize: '14px', fontWeight: 'bold', }); document.body.appendChild(displayDiv); } displayDiv.innerHTML = displayText; } // 清除数据 function clearData() { const date = new Date().toISOString().split('T')[0]; // YYYY-MM-DD 格式 localStorage.removeItem('model_counts'); localStorage.removeItem(`hourly_counts_${date}`); displayCounts(); } // 显示今天模型调用次数和按钮的面板 function showTodayCountsPanel(x, y) { const todayCounts = getTodayCounts(); let panel = document.getElementById('today-counts-panel'); if (!panel) { panel = document.createElement('div'); panel.id = 'today-counts-panel'; Object.assign(panel.style, { position: 'absolute', top: `${y}px`, left: `${x}px`, backgroundColor: 'rgba(255, 255, 255, 0.9)', color: 'black', padding: '10px', border: '1px solid #ccc', borderRadius: '5px', zIndex: '1001', fontSize: '14px', fontWeight: 'bold', maxHeight: '400px', overflowY: 'auto', width: '220px', // 固定宽度 boxShadow: '0px 4px 8px rgba(0,0,0,0.1)', // 阴影效果 }); document.body.appendChild(panel); } let panelContent = '<strong>今天各模型调用次数:</strong><br>'; for (let model in todayCounts) { const icon = modelIcons[model] || '❓'; panelContent += `<div style="display: flex; align-items: center; margin-bottom: 5px;">${icon} ${model}: ${todayCounts[model]}</div>`; } // 添加按钮到面板,垂直排列,并添加hover效果 panelContent += '<hr style="margin: 10px 0;">'; panelContent += '<div style="display: flex; flex-direction: column; align-items: center;">'; panelContent += '<button id="clear-data-button" style="margin: 5px; padding: 8px 16px; width: 100%; border: none; border-radius: 5px; background-color: #f0f0f0; cursor: pointer;">清除数据</button>'; panelContent += '<button id="download-data-button" style="margin: 5px; padding: 8px 16px; width: 100%; border: none; border-radius: 5px; background-color: #f0f0f0; cursor: pointer;">下载数据</button>'; panelContent += '</div>'; panel.innerHTML = panelContent; // 绑定按钮事件 document.getElementById('clear-data-button').onclick = () => { clearData(); panel.style.display = 'none'; }; document.getElementById('download-data-button').onclick = () => { saveDataToFile(); panel.style.display = 'none'; }; // 添加hover效果 const buttons = panel.querySelectorAll('button'); buttons.forEach(button => { button.addEventListener('mouseover', () => { button.style.backgroundColor = '#e0e0e0'; }); button.addEventListener('mouseout', () => { button.style.backgroundColor = '#f0f0f0'; }); }); panel.style.display = 'block'; } // 右键点击事件 window.addEventListener('contextmenu', (e) => { // 只在显示面板上显示菜单 const displayDiv = document.getElementById('model-count-display'); if (displayDiv && displayDiv.contains(e.target)) { e.preventDefault(); showTodayCountsPanel(e.clientX, e.clientY); // 显示今天模型调用次数和按钮的面板 } else { const panel = document.getElementById('today-counts-panel'); if (panel) { panel.style.display = 'none'; } } }); // 点击其他地方隐藏面板 window.addEventListener('click', (e) => { const panel = document.getElementById('today-counts-panel'); if (panel && !panel.contains(e.target)) { panel.style.display = 'none'; } }); displayCounts(); // 初始化显示计数 scheduleHourlySave(); // 开始定时保存 })();
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址