mirror of
https://github.com/woodchen-ink/openai-billing-query.git
synced 2025-07-19 14:32:00 +08:00
Merge branch 'main' of https://github.com/woodchen-ink/openai-billing-query
This commit is contained in:
commit
387fd638f8
12
README.md
12
README.md
@ -3,9 +3,10 @@
|
|||||||
|
|
||||||
star,please.
|
star,please.
|
||||||
|
|
||||||
## [English](README_EN.md)
|
|
||||||
|
|
||||||
Telegram交流群:https://t.me/ai_cn2023
|
Telegram交流群:https://t.me/ai_cn2023
|
||||||
|
QQ群:https://qm.qq.com/q/cCKTiXSn3G
|
||||||
|
|
||||||
|
## [English](README_EN.md)
|
||||||
|
|
||||||
## 最新示意图(2023.08.28)
|
## 最新示意图(2023.08.28)
|
||||||
|
|
||||||
@ -26,6 +27,10 @@ Telegram交流群:https://t.me/ai_cn2023
|
|||||||
## 怎么部署
|
## 怎么部署
|
||||||
下载index.html直接打开就行,除了背景图片,没有任何外部资源。
|
下载index.html直接打开就行,除了背景图片,没有任何外部资源。
|
||||||
|
|
||||||
|
## 赞赏码,如果觉得好用,可以请我喝杯咖啡
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
## 贡献列表
|
## 贡献列表
|
||||||
|
|
||||||
| 人员 | 贡献内容 |
|
| 人员 | 贡献内容 |
|
||||||
@ -39,3 +44,6 @@ Telegram交流群:https://t.me/ai_cn2023
|
|||||||
- [CZLOapi](https://oapi.czl.net),OPENAI代理服务,无需翻墙。
|
- [CZLOapi](https://oapi.czl.net),OPENAI代理服务,无需翻墙。
|
||||||
- 个人博客:https://woodchen.ink
|
- 个人博客:https://woodchen.ink
|
||||||
|
|
||||||
|
## Star History
|
||||||
|
|
||||||
|
[](https://api.star-history.com/svg?repos=woodchen-ink/openai-billing-query&type=Date)
|
||||||
|
22
index.html
22
index.html
@ -8,11 +8,11 @@
|
|||||||
<meta name="description" content="批量快速查询OPENAI的余额,支持可视化展现已用比例、额度、已用量、未用量、是否GPT-4、是否GPT4-32K、是否绑卡、绑卡信息、组织信息、是否有效">
|
<meta name="description" content="批量快速查询OPENAI的余额,支持可视化展现已用比例、额度、已用量、未用量、是否GPT-4、是否GPT4-32K、是否绑卡、绑卡信息、组织信息、是否有效">
|
||||||
<link rel="stylesheet" href="./static/css-1.css" type="text/css" />
|
<link rel="stylesheet" href="./static/css-1.css" type="text/css" />
|
||||||
<script src="https://cdn.tailwindcss.com"></script>
|
<script src="https://cdn.tailwindcss.com"></script>
|
||||||
<link href="https://cdnjs.cloudflare.com/ajax/libs/daisyui/3.6.4/full.min.css" rel="stylesheet" type="text/css" />
|
<link href="https://cdn.staticfile.org/daisyui/3.9.2/full.min.css" rel="stylesheet" type="text/css" />
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body class="bg-gray-900 text-white">
|
<body class="bg-gray-900 text-white">
|
||||||
<div class="container w-full mx-auto lg:flex">
|
<div class="container w-full mx-auto lg:flex ">
|
||||||
<div class="sidebar bg-gray-800 bg-opacity-60 p-8 relative overflow-y-auto lg:w-1/4 md:w-full">
|
<div class="sidebar bg-gray-800 bg-opacity-60 p-8 relative overflow-y-auto lg:w-1/4 md:w-full">
|
||||||
<header>
|
<header>
|
||||||
<h1 class="text-2xl font-semibold mb-8 text-gradient">OpenAI API 信息查询</h1>
|
<h1 class="text-2xl font-semibold mb-8 text-gradient">OpenAI API 信息查询</h1>
|
||||||
@ -80,25 +80,21 @@
|
|||||||
查询
|
查询
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div class="toast invisible md:visible">
|
<div class=" invisible md:visible">
|
||||||
<div class="alert alert-info">
|
<!-- <div class="alert alert-info"> -->
|
||||||
<p>广告链接:
|
|
||||||
<a href="https://chat.czl.net" target="_blank" class="link link-hover">CZLChat</a> <a
|
|
||||||
href="https://oapi.czl.net" target="_blank" class="link link-hover">CZLOapi</a>
|
|
||||||
<a href="https://store0.czl.net" target="_blank" class="link link-hover">CZL Store</a>
|
|
||||||
<br> 本网页由<a href="https://woodchen.ink" target="_blank" class="link link-hover">woodchen</a>开源于<a
|
<br> 本网页由<a href="https://woodchen.ink" target="_blank" class="link link-hover">woodchen</a>开源于<a
|
||||||
href="https://github.com/woodchen-ink/openai-billing-query" target="_blank"
|
href="https://github.com/woodchen-ink/openai-billing-query" target="_blank"
|
||||||
class="link link-hover">Github</a>,欢迎给个star
|
class="link link-hover">Github</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
<!-- </div> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="content pl-6 pt-6 lg:w-3/4 md:w-full">
|
<div class="content pl-6 pt-6 lg:w-3/4 md:w-full overflow-y-auto h-screen">
|
||||||
<h2 class="text-2xl mb-6 font-semibold text-gradient">查询结果</h2>
|
<h2 class="text-2xl mb-6 font-semibold text-gradient">查询结果</h2>
|
||||||
<div class="overflow-x-auto">
|
<div class="overflow-x-auto">
|
||||||
<div class="overflow-y-hidden ">
|
<div class="overflow-y-hidden">
|
||||||
<table id="result-table" class="table table-md border border-slate-500 w-full">
|
<table id="result-table" class="table table-md border border-slate-500 w-full table-pin-rows">
|
||||||
<thead class="text-white border-b border-slate-500">
|
<thead class="text-white border-b border-slate-500">
|
||||||
<tr class="bg-gray-800 bg-opacity-80">
|
<tr class="bg-gray-800 bg-opacity-80">
|
||||||
<th class="w-0.5 border border-slate-500">序号</th>
|
<th class="w-0.5 border border-slate-500">序号</th>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
body {
|
body {
|
||||||
background: url('https://cdn-img.czl.net/2023/05/23/pjbczr.webp') no-repeat center center fixed;
|
background: url('https://cdn-img-r2.czl.net/2023/05/23/pjbczr.webp') no-repeat center center fixed;
|
||||||
background-size:cover;
|
background-size:cover;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -9,7 +9,6 @@ body {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
/* display: flex; */
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
67
static/js.js
67
static/js.js
@ -34,6 +34,14 @@ toggleSetidInfo();
|
|||||||
let queriedApiKeys = [];
|
let queriedApiKeys = [];
|
||||||
let serialNumber = 1;
|
let serialNumber = 1;
|
||||||
|
|
||||||
|
function formatDate(date) {
|
||||||
|
const year = date.getFullYear();
|
||||||
|
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
||||||
|
const day = date.getDate().toString().padStart(2, '0');
|
||||||
|
|
||||||
|
return `${year}-${month}-${day}`;
|
||||||
|
}
|
||||||
|
|
||||||
async function checkBilling(apiKey, apiUrl) {
|
async function checkBilling(apiKey, apiUrl) {
|
||||||
const now = new Date();
|
const now = new Date();
|
||||||
let startDate = new Date(now - 90 * 24 * 60 * 60 * 1000);
|
let startDate = new Date(now - 90 * 24 * 60 * 60 * 1000);
|
||||||
@ -67,14 +75,17 @@ async function checkBilling(apiKey, apiUrl) {
|
|||||||
try {
|
try {
|
||||||
totalAmount = subscriptionData.hard_limit_usd;
|
totalAmount = subscriptionData.hard_limit_usd;
|
||||||
|
|
||||||
|
|
||||||
const advanceDataResponse = await fetch(urlAdvanceData, { headers });
|
const advanceDataResponse = await fetch(urlAdvanceData, { headers });
|
||||||
const advanceData = await advanceDataResponse.json();
|
const advanceData = await advanceDataResponse.json();
|
||||||
|
|
||||||
if ((subscriptionData.billing_mechanism === 'advance') || (totalAmount <= 6 && !subscriptionData.has_credit_card)) {
|
if ((subscriptionData.billing_mechanism === 'advance') || (totalAmount <= 6 && !subscriptionData.has_credit_card)) {
|
||||||
totalAmount = advanceData.total_granted;
|
totalAmount = advanceData.total_granted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
try {
|
||||||
if (totalAmount > 6) {
|
if (totalAmount > 6) {
|
||||||
startDate = subDate;
|
startDate = subDate;
|
||||||
urlUsage = `${apiUrl}/dashboard/billing/usage?start_date=${formatDate(startDate)}&end_date=${formatDate(endDate)}`;
|
urlUsage = `${apiUrl}/dashboard/billing/usage?start_date=${formatDate(startDate)}&end_date=${formatDate(endDate)}`;
|
||||||
@ -83,12 +94,13 @@ async function checkBilling(apiKey, apiUrl) {
|
|||||||
}
|
}
|
||||||
response = await fetch(urlUsage, { headers });
|
response = await fetch(urlUsage, { headers });
|
||||||
const usageData = await response.json();
|
const usageData = await response.json();
|
||||||
|
|
||||||
totalUsage = usageData.total_usage / 100;
|
totalUsage = usageData.total_usage / 100;
|
||||||
remaining = (totalAmount - totalUsage).toFixed(3);
|
remaining = (totalAmount - totalUsage).toFixed(3);
|
||||||
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
errors['subscription'] = error.message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//获取是否绑卡
|
//获取是否绑卡
|
||||||
@ -115,14 +127,13 @@ async function checkBilling(apiKey, apiUrl) {
|
|||||||
}
|
}
|
||||||
//获取绑卡信息
|
//获取绑卡信息
|
||||||
try {
|
try {
|
||||||
// 从 subscriptionData 中获取 SubscribleInformation 的值...
|
|
||||||
SubscribleInformation.account_name = subscriptionData.account_name;
|
SubscribleInformation.account_name = subscriptionData.account_name;
|
||||||
SubscribleInformation.po_number = subscriptionData.po_number;
|
SubscribleInformation.po_number = subscriptionData.po_number;
|
||||||
SubscribleInformation.billing_email = subscriptionData.billing_email;
|
SubscribleInformation.billing_email = subscriptionData.billing_email;
|
||||||
SubscribleInformation.tax_ids = subscriptionData.tax_ids;
|
SubscribleInformation.tax_ids = subscriptionData.tax_ids;
|
||||||
|
|
||||||
let billingAddress = subscriptionData.billing_address; // 定义并赋值 billingAddress
|
let billingAddress = subscriptionData.billing_address;
|
||||||
let businessAddress = subscriptionData.business_address; // 定义并赋值 businessAddress
|
let businessAddress = subscriptionData.business_address;
|
||||||
|
|
||||||
SubInformation = "名称: " + SubscribleInformation.account_name + "\n";
|
SubInformation = "名称: " + SubscribleInformation.account_name + "\n";
|
||||||
SubInformation += "PO号: " + SubscribleInformation.po_number + "\n";
|
SubInformation += "PO号: " + SubscribleInformation.po_number + "\n";
|
||||||
@ -131,7 +142,7 @@ async function checkBilling(apiKey, apiUrl) {
|
|||||||
//使用 JavaScript 的可选链式调用来确定是否为null,避免异常控制台报错
|
//使用 JavaScript 的可选链式调用来确定是否为null,避免异常控制台报错
|
||||||
SubInformation += "账单地址: " + (billingAddress?.line1 ? billingAddress.line1 : '') + ", " + (billingAddress?.city ? billingAddress.city : '') + ", " + (billingAddress?.state ? billingAddress.state : '') + ", " + (billingAddress?.country ? billingAddress.country : '') + ", " + (billingAddress?.postal_code ? billingAddress.postal_code : '') + "\n";
|
SubInformation += "账单地址: " + (billingAddress?.line1 ? billingAddress.line1 : '') + ", " + (billingAddress?.city ? billingAddress.city : '') + ", " + (billingAddress?.state ? billingAddress.state : '') + ", " + (billingAddress?.country ? billingAddress.country : '') + ", " + (billingAddress?.postal_code ? billingAddress.postal_code : '') + "\n";
|
||||||
SubInformation += "商业地址: " + (businessAddress?.line1 ? businessAddress.line1 : '') + ", " + (businessAddress?.city ? businessAddress.city : '') + ", " + (businessAddress?.state ? businessAddress.state : '') + ", " + (businessAddress?.country ? businessAddress.country : '') + ", " + (businessAddress?.postal_code ? businessAddress.postal_code : '\n');
|
SubInformation += "商业地址: " + (businessAddress?.line1 ? businessAddress.line1 : '') + ", " + (businessAddress?.city ? businessAddress.city : '') + ", " + (businessAddress?.state ? businessAddress.state : '') + ", " + (businessAddress?.country ? businessAddress.country : '') + ", " + (businessAddress?.postal_code ? businessAddress.postal_code : '\n');
|
||||||
// 获取付款方法信息
|
|
||||||
response = await fetch(urlPaymentmethods, { headers });
|
response = await fetch(urlPaymentmethods, { headers });
|
||||||
const paymentMethodsData = await response.json();
|
const paymentMethodsData = await response.json();
|
||||||
|
|
||||||
@ -216,8 +227,9 @@ async function checkBilling(apiKey, apiUrl) {
|
|||||||
GPT432kCheckResult = Array.isArray(modelsCheckData.data) && modelsCheckData.data.some(item => item.id.includes('gpt-4-32k')) ? '✅' : '❌';
|
GPT432kCheckResult = Array.isArray(modelsCheckData.data) && modelsCheckData.data.some(item => item.id.includes('gpt-4-32k')) ? '✅' : '❌';
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
errors['modelsCheck'] = error.message;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 发起请求查有效
|
||||||
async function checkCompletion(apiKey, apiUrl) {
|
async function checkCompletion(apiKey, apiUrl) {
|
||||||
const urlCompletion = `${apiUrl}/chat/completions`;
|
const urlCompletion = `${apiUrl}/chat/completions`;
|
||||||
const headers = {
|
const headers = {
|
||||||
@ -256,17 +268,12 @@ async function checkBilling(apiKey, apiUrl) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatDate(date) {
|
|
||||||
const year = date.getFullYear();
|
|
||||||
const month = (date.getMonth() + 1).toString().padStart(2, '0');
|
|
||||||
const day = date.getDate().toString().padStart(2, '0');
|
|
||||||
|
|
||||||
return `${year}-${month}-${day}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
//查询函数
|
//查询函数
|
||||||
function sendRequest() {
|
function sendRequest() {
|
||||||
showLoadingAnimation();
|
showLoadingAnimation();
|
||||||
|
toggleProgressBar();
|
||||||
toggleSubInfo();
|
toggleSubInfo();
|
||||||
toggleSetidInfo();
|
toggleSetidInfo();
|
||||||
|
|
||||||
@ -378,26 +385,31 @@ function sendRequest() {
|
|||||||
let totalAmount = document.createElement("td");
|
let totalAmount = document.createElement("td");
|
||||||
totalAmount.classList.add("border");
|
totalAmount.classList.add("border");
|
||||||
totalAmount.classList.add("border-slate-500");
|
totalAmount.classList.add("border-slate-500");
|
||||||
totalAmount.textContent = data[0];
|
totalAmount.textContent = typeof data[0] === "number" ? data[0] : "无值";
|
||||||
row.appendChild(totalAmount);
|
row.appendChild(totalAmount);
|
||||||
|
|
||||||
let totalUsedCell = document.createElement("td");
|
let totalUsedCell = document.createElement("td");
|
||||||
totalUsedCell.classList.add("border");
|
totalUsedCell.classList.add("border");
|
||||||
totalUsedCell.classList.add("border-slate-500");
|
totalUsedCell.classList.add("border-slate-500");
|
||||||
if (!isNaN(data[1])) {
|
typeof data[1] === "number" ? data[1].toFixed(3) : '无值';
|
||||||
|
if(isNaN(data[1])){
|
||||||
|
totalUsedCell.textContent = "无值";
|
||||||
|
}else{
|
||||||
totalUsedCell.textContent = data[1].toFixed(3);
|
totalUsedCell.textContent = data[1].toFixed(3);
|
||||||
} else {
|
|
||||||
totalUsedCell.textContent = '❌'
|
|
||||||
}
|
}
|
||||||
row.appendChild(totalUsedCell);
|
row.appendChild(totalUsedCell);
|
||||||
|
|
||||||
let totalAvailableCell = document.createElement("td");
|
let totalAvailableCell = document.createElement("td");
|
||||||
totalAvailableCell.classList.add("border");
|
totalAvailableCell.classList.add("border");
|
||||||
totalAvailableCell.classList.add("border-slate-500");
|
totalAvailableCell.classList.add("border-slate-500");
|
||||||
totalAvailableCell.textContent = typeof data[2] === 'number' ? data[2] : data[2];
|
if(isNaN(data[2])){
|
||||||
|
totalAvailableCell.textContent = "无值";
|
||||||
|
}else{
|
||||||
|
totalAvailableCell.textContent = data[2];
|
||||||
|
}
|
||||||
row.appendChild(totalAvailableCell);
|
row.appendChild(totalAvailableCell);
|
||||||
|
|
||||||
|
// 进度条
|
||||||
let progressCell = document.createElement("td");
|
let progressCell = document.createElement("td");
|
||||||
progressCell.classList.add("progressbar");
|
progressCell.classList.add("progressbar");
|
||||||
progressCell.classList.add("border");
|
progressCell.classList.add("border");
|
||||||
@ -425,7 +437,13 @@ function sendRequest() {
|
|||||||
let expireTime = document.createElement("td");
|
let expireTime = document.createElement("td");
|
||||||
expireTime.classList.add("border");
|
expireTime.classList.add("border");
|
||||||
expireTime.classList.add("border-slate-500");
|
expireTime.classList.add("border-slate-500");
|
||||||
expireTime.textContent = data[3];
|
if (data[3] === "1970-01-01") {
|
||||||
|
expireTime.textContent = "永久有效";
|
||||||
|
}else if(data[3] === "NaN-NaN-NaN"){
|
||||||
|
expireTime.textContent = "无值";
|
||||||
|
}else{
|
||||||
|
expireTime.textContent = data[3];
|
||||||
|
}
|
||||||
row.appendChild(expireTime);
|
row.appendChild(expireTime);
|
||||||
|
|
||||||
|
|
||||||
@ -455,6 +473,12 @@ function sendRequest() {
|
|||||||
isSubscribe.classList.add("border-slate-500");
|
isSubscribe.classList.add("border-slate-500");
|
||||||
isSubscribe.style.whiteSpace = "pre"; // 添加这一行来保留换行
|
isSubscribe.style.whiteSpace = "pre"; // 添加这一行来保留换行
|
||||||
isSubscribe.textContent = data[7];
|
isSubscribe.textContent = data[7];
|
||||||
|
if (data[7] === "Not Found.") {
|
||||||
|
isSubscribe.textContent = "无值";
|
||||||
|
} else {
|
||||||
|
isSubscribe.textContent = data[7];
|
||||||
|
}
|
||||||
|
|
||||||
row.appendChild(isSubscribe);
|
row.appendChild(isSubscribe);
|
||||||
|
|
||||||
let SubInformation = document.createElement("td");
|
let SubInformation = document.createElement("td");
|
||||||
@ -530,7 +554,6 @@ function sendRequest() {
|
|||||||
queriedApiKeys = [];
|
queriedApiKeys = [];
|
||||||
}
|
}
|
||||||
serialNumber++; // 增加序列号
|
serialNumber++; // 增加序列号
|
||||||
// h2.style.display = 'block';
|
|
||||||
table.style.display = 'table';
|
table.style.display = 'table';
|
||||||
|
|
||||||
hideLoadingAnimation();
|
hideLoadingAnimation();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user