mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-14 09:56:06 +08:00
feat: spark free quota verify (#1152)
This commit is contained in:
parent
24cb992843
commit
96d10c8b39
@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||||
import { useRouter, useSearchParams } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import useSWRInfinite from 'swr/infinite'
|
import useSWRInfinite from 'swr/infinite'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import AppCard from './AppCard'
|
import AppCard from './AppCard'
|
||||||
@ -10,8 +10,11 @@ import type { AppListResponse } from '@/models/app'
|
|||||||
import { fetchAppList } from '@/service/apps'
|
import { fetchAppList } from '@/service/apps'
|
||||||
import { useAppContext } from '@/context/app-context'
|
import { useAppContext } from '@/context/app-context'
|
||||||
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
|
||||||
import { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
|
|
||||||
import Confirm from '@/app/components/base/confirm/common'
|
import Confirm from '@/app/components/base/confirm/common'
|
||||||
|
import {
|
||||||
|
useAnthropicCheckPay,
|
||||||
|
useSparkCheckQuota,
|
||||||
|
} from '@/hooks/use-pay'
|
||||||
|
|
||||||
const getKey = (pageIndex: number, previousPageData: AppListResponse) => {
|
const getKey = (pageIndex: number, previousPageData: AppListResponse) => {
|
||||||
if (!pageIndex || previousPageData.has_more)
|
if (!pageIndex || previousPageData.has_more)
|
||||||
@ -24,11 +27,10 @@ const Apps = () => {
|
|||||||
const { isCurrentWorkspaceManager } = useAppContext()
|
const { isCurrentWorkspaceManager } = useAppContext()
|
||||||
const { data, isLoading, setSize, mutate } = useSWRInfinite(getKey, fetchAppList, { revalidateFirstPage: false })
|
const { data, isLoading, setSize, mutate } = useSWRInfinite(getKey, fetchAppList, { revalidateFirstPage: false })
|
||||||
const anchorRef = useRef<HTMLDivElement>(null)
|
const anchorRef = useRef<HTMLDivElement>(null)
|
||||||
const searchParams = useSearchParams()
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
const payProviderName = searchParams.get('provider_name')
|
const [showPayStatusModal, setShowPayStatusModal] = useState(true)
|
||||||
const payStatus = searchParams.get('payment_result')
|
const anthropicConfirmInfo = useAnthropicCheckPay()
|
||||||
const [showPayStatusModal, setShowPayStatusModal] = useState(false)
|
const sparkConfirmInfo = useSparkCheckQuota()
|
||||||
|
|
||||||
const handleCancelShowPayStatusModal = useCallback(() => {
|
const handleCancelShowPayStatusModal = useCallback(() => {
|
||||||
setShowPayStatusModal(false)
|
setShowPayStatusModal(false)
|
||||||
@ -41,9 +43,7 @@ const Apps = () => {
|
|||||||
localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY)
|
localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY)
|
||||||
mutate()
|
mutate()
|
||||||
}
|
}
|
||||||
if (payProviderName === ProviderEnum.anthropic && (payStatus === 'succeeded' || payStatus === 'cancelled'))
|
}, [mutate, t])
|
||||||
setShowPayStatusModal(true)
|
|
||||||
}, [mutate, payProviderName, payStatus, t])
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let observer: IntersectionObserver | undefined
|
let observer: IntersectionObserver | undefined
|
||||||
@ -65,23 +65,29 @@ const Apps = () => {
|
|||||||
<AppCard key={app.id} app={app} onRefresh={mutate} />
|
<AppCard key={app.id} app={app} onRefresh={mutate} />
|
||||||
)))}
|
)))}
|
||||||
{
|
{
|
||||||
showPayStatusModal && (
|
showPayStatusModal && anthropicConfirmInfo && (
|
||||||
<Confirm
|
<Confirm
|
||||||
isShow
|
isShow
|
||||||
onCancel={handleCancelShowPayStatusModal}
|
onCancel={handleCancelShowPayStatusModal}
|
||||||
onConfirm={handleCancelShowPayStatusModal}
|
onConfirm={handleCancelShowPayStatusModal}
|
||||||
type={
|
type={anthropicConfirmInfo.type}
|
||||||
payStatus === 'succeeded'
|
title={anthropicConfirmInfo.title}
|
||||||
? 'success'
|
|
||||||
: 'danger'
|
|
||||||
}
|
|
||||||
title={
|
|
||||||
payStatus === 'succeeded'
|
|
||||||
? t('common.actionMsg.paySucceeded')
|
|
||||||
: t('common.actionMsg.payCancelled')
|
|
||||||
}
|
|
||||||
showOperateCancel={false}
|
showOperateCancel={false}
|
||||||
confirmText={(payStatus === 'cancelled' && t('common.operation.ok')) || ''}
|
confirmText={(anthropicConfirmInfo.type === 'danger' && t('common.operation.ok')) || ''}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
{
|
||||||
|
showPayStatusModal && sparkConfirmInfo && (
|
||||||
|
<Confirm
|
||||||
|
isShow
|
||||||
|
onCancel={handleCancelShowPayStatusModal}
|
||||||
|
onConfirm={handleCancelShowPayStatusModal}
|
||||||
|
type={sparkConfirmInfo.type}
|
||||||
|
title={sparkConfirmInfo.title}
|
||||||
|
desc={sparkConfirmInfo.desc}
|
||||||
|
showOperateCancel={false}
|
||||||
|
confirmText={(sparkConfirmInfo.type === 'danger' && t('common.operation.ok')) || ''}
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ const Popup: FC<PopupProps> = ({
|
|||||||
<Link
|
<Link
|
||||||
href={`/datasets/${source.dataset_id}/documents/${source.document_id}`}
|
href={`/datasets/${source.dataset_id}/documents/${source.document_id}`}
|
||||||
className='hidden items-center h-[18px] text-xs text-primary-600 group-hover:flex'>
|
className='hidden items-center h-[18px] text-xs text-primary-600 group-hover:flex'>
|
||||||
Link to dataset
|
{t('common.chat.citation.linkToDataset')}
|
||||||
<ArrowUpRight className='ml-1 w-3 h-3' />
|
<ArrowUpRight className='ml-1 w-3 h-3' />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -8,7 +8,7 @@ import { AlertCircle } from '@/app/components/base/icons/src/vender/solid/alerts
|
|||||||
import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general'
|
import { CheckCircle } from '@/app/components/base/icons/src/vender/solid/general'
|
||||||
import Button from '@/app/components/base/button'
|
import Button from '@/app/components/base/button'
|
||||||
|
|
||||||
type ConfirmCommonProps = {
|
export type ConfirmCommonProps = {
|
||||||
type?: string
|
type?: string
|
||||||
isShow: boolean
|
isShow: boolean
|
||||||
onCancel: () => void
|
onCancel: () => void
|
||||||
|
71
web/hooks/use-pay.ts
Normal file
71
web/hooks/use-pay.ts
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
'use client'
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import useSWR from 'swr'
|
||||||
|
import { useSearchParams } from 'next/navigation'
|
||||||
|
import { useContext } from 'use-context-selector'
|
||||||
|
import I18n from '@/context/i18n'
|
||||||
|
import { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations'
|
||||||
|
import { fetchSparkFreeQuotaVerify } from '@/service/common'
|
||||||
|
import type { ConfirmCommonProps } from '@/app/components/base/confirm/common'
|
||||||
|
|
||||||
|
export type ConfirmType = Pick<ConfirmCommonProps, 'type' | 'title' | 'desc'>
|
||||||
|
|
||||||
|
export const useAnthropicCheckPay = () => {
|
||||||
|
const { t } = useTranslation()
|
||||||
|
const [confirm, setConfirm] = useState<ConfirmType | null>(null)
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
const providerName = searchParams.get('provider_name')
|
||||||
|
const paymentResult = searchParams.get('payment_result')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (providerName === ProviderEnum.anthropic && (paymentResult === 'succeeded' || paymentResult === 'cancelled')) {
|
||||||
|
setConfirm({
|
||||||
|
type: paymentResult === 'succeeded' ? 'success' : 'danger',
|
||||||
|
title: paymentResult === 'succeeded' ? t('common.actionMsg.paySucceeded') : t('common.actionMsg.payCancelled'),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [providerName, paymentResult, t])
|
||||||
|
|
||||||
|
return confirm
|
||||||
|
}
|
||||||
|
|
||||||
|
const QUOTA_RECEIVE_STATUS = {
|
||||||
|
success: {
|
||||||
|
'en': 'Anthropic',
|
||||||
|
'zh-Hans': '领取成功,将在 5 分钟后自动增加配额',
|
||||||
|
},
|
||||||
|
fail: {
|
||||||
|
'en': 'Anthropic',
|
||||||
|
'zh-Hans': '领取失败',
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
export const useSparkCheckQuota = () => {
|
||||||
|
const { locale } = useContext(I18n)
|
||||||
|
const [shouldVerify, setShouldVerify] = useState(false)
|
||||||
|
const { data } = useSWR(
|
||||||
|
shouldVerify
|
||||||
|
? `/workspaces/current/model-providers/${ProviderEnum.spark}/free-quota-qualification-verify`
|
||||||
|
: null,
|
||||||
|
fetchSparkFreeQuotaVerify,
|
||||||
|
)
|
||||||
|
const searchParams = useSearchParams()
|
||||||
|
const type = searchParams.get('type')
|
||||||
|
const provider = searchParams.get('provider')
|
||||||
|
const result = searchParams.get('result')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (type === 'provider_apply_callback' && provider === ProviderEnum.spark && result === 'success')
|
||||||
|
setShouldVerify(true)
|
||||||
|
}, [type, provider, result])
|
||||||
|
|
||||||
|
return data
|
||||||
|
? {
|
||||||
|
type: data.flag ? 'success' : 'danger',
|
||||||
|
title: data.flag ? QUOTA_RECEIVE_STATUS.success[locale] : QUOTA_RECEIVE_STATUS.fail[locale],
|
||||||
|
desc: !data.flag ? data.reason : undefined,
|
||||||
|
}
|
||||||
|
: null
|
||||||
|
}
|
@ -345,7 +345,7 @@ const translation = {
|
|||||||
conversationNameCanNotEmpty: '会话名称必填',
|
conversationNameCanNotEmpty: '会话名称必填',
|
||||||
citation: {
|
citation: {
|
||||||
title: '引用',
|
title: '引用',
|
||||||
linkToDataset: '去往数据集',
|
linkToDataset: '跳转至数据集',
|
||||||
characters: '字符:',
|
characters: '字符:',
|
||||||
hitCount: '命中次数:',
|
hitCount: '命中次数:',
|
||||||
vectorHash: '向量哈希:',
|
vectorHash: '向量哈希:',
|
||||||
|
@ -184,3 +184,7 @@ export const fetchFileUploadConfig: Fetcher<FileUploadConfigResponse, { url: str
|
|||||||
export const fetchDocumentsLimit: Fetcher<DocumentsLimitResponse, string> = (url) => {
|
export const fetchDocumentsLimit: Fetcher<DocumentsLimitResponse, string> = (url) => {
|
||||||
return get(url) as Promise<DocumentsLimitResponse>
|
return get(url) as Promise<DocumentsLimitResponse>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const fetchSparkFreeQuotaVerify: Fetcher<{ result: string; flag: boolean; reason: string }, string> = (url) => {
|
||||||
|
return get(url) as Promise<{ result: string; flag: boolean; reason: string }>
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user