This commit is contained in:
wood 2023-10-20 20:18:58 +08:00
commit 387fd638f8
4 changed files with 65 additions and 39 deletions

View File

@ -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直接打开就行除了背景图片没有任何外部资源。
## 赞赏码,如果觉得好用,可以请我喝杯咖啡
![IMG_1768.png](https://cdn-img-r2.czl.net/2023/10/13/6528c3c44100a.png)
## 贡献列表 ## 贡献列表
| 人员 | 贡献内容 | | 人员 | 贡献内容 |
@ -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
[![Star History Chart](https://api.star-history.com/svg?repos=woodchen-ink/openai-billing-query&type=Date)](https://api.star-history.com/svg?repos=woodchen-ink/openai-billing-query&type=Date)

View File

@ -8,7 +8,7 @@
<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">
@ -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>

View File

@ -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%;
} }

View File

@ -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) : '无值';
totalUsedCell.textContent = data[1].toFixed(3); if(isNaN(data[1])){
totalUsedCell.textContent = "无值";
}else{ }else{
totalUsedCell.textContent = '❌' totalUsedCell.textContent = data[1].toFixed(3);
} }
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");
if (data[3] === "1970-01-01") {
expireTime.textContent = "永久有效";
}else if(data[3] === "NaN-NaN-NaN"){
expireTime.textContent = "无值";
}else{
expireTime.textContent = data[3]; 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();