From 79a27267a985c01b8076ea8ddf486fe88a9cdfe4 Mon Sep 17 00:00:00 2001 From: wangxi <112324550+luckywangxi@users.noreply.github.com> Date: Tue, 4 Apr 2023 08:27:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BF=AE=E5=A4=8DAPI=E4=BD=99=E9=A2=9D?= =?UTF-8?q?=E6=9F=A5=E8=AF=A2=20(#1174)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 使API余额查询可用 * chore: 调整计算方式 * perf: 余额描述变更 --------- Co-authored-by: ChenZhaoYu <790348264@qq.com> --- service/src/chatgpt/index.ts | 61 +++++++++++-------------- service/src/chatgpt/types.ts | 4 ++ src/components/common/Setting/About.vue | 3 +- src/locales/en-US.ts | 2 +- src/locales/zh-CN.ts | 2 +- src/locales/zh-TW.ts | 2 +- 6 files changed, 35 insertions(+), 39 deletions(-) diff --git a/service/src/chatgpt/index.ts b/service/src/chatgpt/index.ts index a179e9690f..b5aea1689d 100644 --- a/service/src/chatgpt/index.ts +++ b/service/src/chatgpt/index.ts @@ -5,12 +5,10 @@ import { ChatGPTAPI, ChatGPTUnofficialProxyAPI } from 'chatgpt' import { SocksProxyAgent } from 'socks-proxy-agent' import httpsProxyAgent from 'https-proxy-agent' import fetch from 'node-fetch' -import axios from 'axios' import { sendResponse } from '../utils' import { isNotEmptyString } from '../utils/is' import type { ApiModel, ChatContext, ChatGPTUnofficialProxyAPIOptions, ModelConfig } from '../types' -import type { RequestOptions } from './types' -import { messageStore } from '../store' +import type { BalanceResponse, RequestOptions } from './types' const { HttpsProxyAgent } = httpsProxyAgent @@ -128,6 +126,8 @@ async function chatReplyProcess(options: RequestOptions) { } async function fetchBalance() { + // 计算起始日期和结束日期 + const OPENAI_API_KEY = process.env.OPENAI_API_KEY const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL @@ -136,49 +136,40 @@ async function fetchBalance() { const API_BASE_URL = isNotEmptyString(OPENAI_API_BASE_URL) ? OPENAI_API_BASE_URL - : 'https://api.openai.com/v1' + : 'https://api.openai.com' - try { - const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${OPENAI_API_KEY}` } - const response = await axios.get(`${API_BASE_URL}/dashboard/billing/credit_grants`, { headers }) - const balance = response.data.total_available ?? 0 - return balance.toFixed(3) - } - catch { - return '-' - } -} + const [startDate, endDate] = formatDate() -async function fetchMonthlyUsage() { - const OPENAI_API_KEY = process.env.OPENAI_API_KEY - const OPENAI_API_BASE_URL = process.env.OPENAI_API_BASE_URL + // 每月使用量 + const urlUsage = `${API_BASE_URL}/v1/dashboard/billing/usage?start_date=${startDate}&end_date=${endDate}` - if (!isNotEmptyString(OPENAI_API_KEY)) - return '-' - - const API_BASE_URL = isNotEmptyString(OPENAI_API_BASE_URL) - ? OPENAI_API_BASE_URL - : 'https://api.openai.com/v1' - - const now = new Date() - const startOfMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), 1)) - const startOfNextMonth = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth() + 1, 1)) + const headers = { + 'Authorization': `Bearer ${OPENAI_API_KEY}`, + 'Content-Type': 'application/json', + } try { - const headers = { 'Content-Type': 'application/json', 'Authorization': `Bearer ${OPENAI_API_KEY}` } - const params = { - 'start_date': startOfMonth.toISOString().substring(0, 10), - 'end_date': startOfNextMonth.toISOString().substring(0, 10), - } - const response = await axios.get(`${API_BASE_URL}/dashboard/billing/usage`, { headers, params }) - const monthlyUsage = (response.data.total_usage ?? 0) / 100 - return monthlyUsage.toFixed(3) + // 获取已使用量 + const useResponse = await fetch(urlUsage, { headers }) + const usageData = await useResponse.json() as BalanceResponse + const usage = Math.round(usageData.total_usage) / 100 + return Promise.resolve(usage ? `$${usage}` : '-') } catch { return '-' } } +function formatDate(): string[] { + const today = new Date() + const year = today.getFullYear() + const month = today.getMonth() + 1 + const lastDay = new Date(year, month, 0) + const formattedFirstDay = `${year}-${month.toString().padStart(2, '0')}-01` + const formattedLastDay = `${year}-${month.toString().padStart(2, '0')}-${lastDay.getDate().toString().padStart(2, '0')}` + return [formattedFirstDay, formattedLastDay] +} + async function chatConfig() { // const balance = await fetchBalance() const monthlyUsage = await fetchMonthlyUsage() diff --git a/service/src/chatgpt/types.ts b/service/src/chatgpt/types.ts index 75b3557904..f53f9fc27d 100644 --- a/service/src/chatgpt/types.ts +++ b/service/src/chatgpt/types.ts @@ -8,3 +8,7 @@ export interface RequestOptions { temperature?: number topP?: number } + +export interface BalanceResponse { + total_usage: number +} diff --git a/src/components/common/Setting/About.vue b/src/components/common/Setting/About.vue index fe36f67226..78798b4eaa 100644 --- a/src/components/common/Setting/About.vue +++ b/src/components/common/Setting/About.vue @@ -63,7 +63,8 @@ onMounted(() => {

{{ $t("setting.api") }}:{{ config?.apiModel ?? '-' }}

- {{ $t("setting.monthlyUsage") }}:${{ config?.monthlyUsage ?? '-' }} + {{ $t("setting.balance") }}:{{ config?.balance ?? '-' }} + ({{ $t('setting.monthlyUsage') }})

{{ $t("setting.reverseProxy") }}:{{ config?.reverseProxy ?? '-' }} diff --git a/src/locales/en-US.ts b/src/locales/en-US.ts index d41600c56a..f62236dd4a 100644 --- a/src/locales/en-US.ts +++ b/src/locales/en-US.ts @@ -73,7 +73,7 @@ export default { socks: 'Socks', httpsProxy: 'HTTPS Proxy', balance: 'API Balance', - monthlyUsage: 'Monthly usage', + monthlyUsage: 'Monthly Usage', }, store: { siderButton: 'Prompt Store', diff --git a/src/locales/zh-CN.ts b/src/locales/zh-CN.ts index adbcb58c48..f46574381e 100644 --- a/src/locales/zh-CN.ts +++ b/src/locales/zh-CN.ts @@ -73,7 +73,7 @@ export default { socks: 'Socks', httpsProxy: 'HTTPS Proxy', balance: 'API余额', - monthlyUsage: '本月用量', + monthlyUsage: '本月使用量', }, store: { siderButton: '提示词商店', diff --git a/src/locales/zh-TW.ts b/src/locales/zh-TW.ts index 1c13b2b5ac..eeb8b11de4 100644 --- a/src/locales/zh-TW.ts +++ b/src/locales/zh-TW.ts @@ -71,7 +71,7 @@ export default { socks: 'Socks', httpsProxy: 'HTTPS Proxy', balance: 'API余額', - monthlyUsage: '本月用量', + monthlyUsage: '本月使用量', }, store: { siderButton: '提示詞商店',