|
@@ -3,18 +3,17 @@ import type { FC } from 'react'
|
|
|
import React, { useState } from 'react'
|
|
|
import { useTranslation } from 'react-i18next'
|
|
|
import cn from 'classnames'
|
|
|
-import useSWR from 'swr'
|
|
|
import Progress from './progress'
|
|
|
import Button from '@/app/components/base/button'
|
|
|
import { LinkExternal02, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
|
|
import AccountSetting from '@/app/components/header/account-setting'
|
|
|
-import { fetchTenantInfo } from '@/service/common'
|
|
|
import { IS_CE_EDITION } from '@/config'
|
|
|
import { useProviderContext } from '@/context/provider-context'
|
|
|
+import { formatNumber } from '@/utils/format'
|
|
|
|
|
|
const APIKeyInfoPanel: FC = () => {
|
|
|
const isCloud = !IS_CE_EDITION
|
|
|
- const { providers }: any = useProviderContext()
|
|
|
+ const { textGenerationModelList } = useProviderContext()
|
|
|
|
|
|
const { t } = useTranslation()
|
|
|
|
|
@@ -22,37 +21,42 @@ const APIKeyInfoPanel: FC = () => {
|
|
|
|
|
|
const [isShow, setIsShow] = useState(true)
|
|
|
|
|
|
- const { data: userInfo } = useSWR({ url: '/info' }, fetchTenantInfo)
|
|
|
- if (!userInfo)
|
|
|
- return null
|
|
|
+ const hasSetAPIKEY = !!textGenerationModelList?.find(({ model_provider: provider }) => {
|
|
|
+ if (provider.provider_type === 'system' && provider.quota_type === 'paid')
|
|
|
+ return true
|
|
|
+
|
|
|
+ if (provider.provider_type === 'custom')
|
|
|
+ return true
|
|
|
|
|
|
- const hasBindAPI = userInfo?.providers?.find(({ token_is_set }) => token_is_set)
|
|
|
- if (hasBindAPI)
|
|
|
+ return false
|
|
|
+ })
|
|
|
+ if (hasSetAPIKEY)
|
|
|
return null
|
|
|
|
|
|
// first show in trail and not used exhausted, else find the exhausted
|
|
|
- const [used, total, providerName] = (() => {
|
|
|
- if (!providers || !isCloud)
|
|
|
+ const [used, total, unit, providerName] = (() => {
|
|
|
+ if (!textGenerationModelList || !isCloud)
|
|
|
return [0, 0, '']
|
|
|
let used = 0
|
|
|
let total = 0
|
|
|
+ let unit = 'times'
|
|
|
let trailProviderName = ''
|
|
|
let hasFoundNotExhausted = false
|
|
|
- Object.keys(providers).forEach((providerName) => {
|
|
|
+ textGenerationModelList?.filter(({ model_provider: provider }) => {
|
|
|
+ return provider.quota_type === 'trial'
|
|
|
+ }).forEach(({ model_provider: provider }) => {
|
|
|
if (hasFoundNotExhausted)
|
|
|
return
|
|
|
- providers[providerName].providers.forEach(({ quota_type, quota_limit, quota_used }: any) => {
|
|
|
- if (quota_type === 'trial') {
|
|
|
- if (quota_limit !== quota_used)
|
|
|
- hasFoundNotExhausted = true
|
|
|
-
|
|
|
- used = quota_used
|
|
|
- total = quota_limit
|
|
|
- trailProviderName = providerName
|
|
|
- }
|
|
|
- })
|
|
|
+ const { provider_name, quota_used, quota_limit, quota_unit } = provider
|
|
|
+ if (quota_limit !== quota_used)
|
|
|
+ hasFoundNotExhausted = true
|
|
|
+ used = quota_used
|
|
|
+ total = quota_limit
|
|
|
+ unit = quota_unit
|
|
|
+ trailProviderName = provider_name
|
|
|
})
|
|
|
- return [used, total, trailProviderName]
|
|
|
+
|
|
|
+ return [used, total, unit, trailProviderName]
|
|
|
})()
|
|
|
const usedPercent = Math.round(used / total * 100)
|
|
|
const exhausted = isCloud && usedPercent === 100
|
|
@@ -81,9 +85,9 @@ const APIKeyInfoPanel: FC = () => {
|
|
|
{isCloud && (
|
|
|
<div className='my-5'>
|
|
|
<div className='flex items-center h-5 space-x-2 text-sm text-gray-700 font-medium'>
|
|
|
- <div>{t('appOverview.apiKeyInfo.callTimes')}</div>
|
|
|
+ <div>{t(`appOverview.apiKeyInfo.${unit === 'times' ? 'callTimes' : 'usedToken'}`)}</div>
|
|
|
<div>·</div>
|
|
|
- <div className={cn('font-semibold', exhausted && 'text-[#D92D20]')}>{used}/{total}</div>
|
|
|
+ <div className={cn('font-semibold', exhausted && 'text-[#D92D20]')}>{formatNumber(used)}/{formatNumber(total)}</div>
|
|
|
</div>
|
|
|
<Progress className='mt-2' value={usedPercent} />
|
|
|
</div>
|