Skip to content

Instantly share code, notes, and snippets.

@maicss
Last active March 13, 2026 12:01
Show Gist options
  • Select an option

  • Save maicss/eab15f41c9f38d9655c17a67a9efe868 to your computer and use it in GitHub Desktop.

Select an option

Save maicss/eab15f41c9f38d9655c17a67a9efe868 to your computer and use it in GitHub Desktop.
Z.ai Quota Reset Time Display
// ==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