Last active
March 13, 2026 12:01
-
-
Save maicss/eab15f41c9f38d9655c17a67a9efe868 to your computer and use it in GitHub Desktop.
Z.ai Quota Reset Time Display
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // ==UserScript== | |
| // @name Z.ai Quota Reset Time Display | |
| // @namespace http://tampermonkey.net/ | |
| // @version 1.0 | |
| // @description 捕获配额接口获取日期并写到界面上 | |
| // @author Maicss | |
| // @match https://z.ai/manage-apikey/subscription | |
| // @run-at document-start | |
| // @grant none | |
| // ==/UserScript== | |
| (function() { | |
| 'use strict'; | |
| const TARGET_PATH = '/api/monitor/usage/quota/limit'; | |
| console.log('%c[Z.ai Helper] 脚本已加载,开始监听接口...', 'color: #ff8c00; font-weight: bold;'); | |
| // 格式化日期为东八区 | |
| function formatToChinaTime(timestamp) { | |
| const date = new Date(timestamp); | |
| return date.toLocaleString('zh-CN', { | |
| timeZone: 'Asia/Shanghai', | |
| hour12: false, | |
| year: 'numeric', | |
| month: '2-digit', | |
| day: '2-digit', | |
| hour: '2-digit', | |
| minute: '2-digit', | |
| second: '2-digit' | |
| }); | |
| } | |
| // UI 注入逻辑 | |
| function injectResetTime(nextResetTime) { | |
| const timeStr = formatToChinaTime(nextResetTime); | |
| // 寻找目标 DOM | |
| let targetContainer = document.querySelector('div[class*="subscription_usage-limit-card__"] ul li div') | |
| if (targetContainer) { | |
| let displaySpan = document.getElementById('tm-quota-reset-box'); | |
| if (!displaySpan) { | |
| displaySpan = document.createElement('span'); | |
| displaySpan.id = 'tm-quota-reset-box'; | |
| displaySpan.style.cssText = ` | |
| margin-left: auto; | |
| font-size: 13px; | |
| color: #63b3ed; | |
| font-weight: 500; | |
| background: rgba(66, 153, 225, 0.15); | |
| padding: 2px 8px; | |
| border-radius: 4px; | |
| border: 1px solid rgba(99, 179, 237, 0.3); | |
| `; | |
| targetContainer.style.display = 'flex'; | |
| targetContainer.style.alignItems = 'center'; | |
| targetContainer.style.width = '100%'; | |
| targetContainer.appendChild(displaySpan); | |
| } | |
| displaySpan.innerText = '重置时间: ' + timeStr; | |
| console.log('[Z.ai Helper] UI 已成功更新时间'); | |
| } else { | |
| console.error('[Z.ai Helper] 没有找到目标 DOM') | |
| } | |
| } | |
| // 1. 处理数据解析的通用函数 | |
| function handleResponseData(data) { | |
| if (data?.success && data?.data?.limits) { | |
| const timeLimit = data.data.limits.find(l => l.type === "TOKENS_LIMIT"); | |
| if (timeLimit && timeLimit.nextResetTime) { | |
| console.log(`%c[Z.ai Helper] 成功捕获数据! NextReset: ${timeLimit.nextResetTime}`, 'color: #48bb78; font-weight: bold'); | |
| setTimeout(() => injectResetTime(timeLimit.nextResetTime), 500); | |
| } | |
| } | |
| } | |
| // 2. 劫持 XMLHttpRequest | |
| const originalXHR = window.XMLHttpRequest.prototype.open; | |
| window.XMLHttpRequest.prototype.open = function(method, url) { | |
| this.addEventListener('load', function() { | |
| if (url.includes(TARGET_PATH)) { | |
| console.log(`[Z.ai Helper] XHR 拦截到目标请求: ${url}`); | |
| try { | |
| const data = JSON.parse(this.responseText); | |
| handleResponseData(data); | |
| } catch (e) {} | |
| } | |
| }); | |
| return originalXHR.apply(this, arguments); | |
| }; | |
| })(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment