diff --git a/web/app/(commonLayout)/apps/Apps.tsx b/web/app/(commonLayout)/apps/Apps.tsx index 37bfaa8b78..cf4ae86e8a 100644 --- a/web/app/(commonLayout)/apps/Apps.tsx +++ b/web/app/(commonLayout)/apps/Apps.tsx @@ -1,7 +1,7 @@ 'use client' import { useCallback, useEffect, useRef, useState } from 'react' -import { useRouter, useSearchParams } from 'next/navigation' +import { useRouter } from 'next/navigation' import useSWRInfinite from 'swr/infinite' import { useTranslation } from 'react-i18next' import AppCard from './AppCard' @@ -10,8 +10,11 @@ import type { AppListResponse } from '@/models/app' import { fetchAppList } from '@/service/apps' import { useAppContext } from '@/context/app-context' 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 { + useAnthropicCheckPay, + useSparkCheckQuota, +} from '@/hooks/use-pay' const getKey = (pageIndex: number, previousPageData: AppListResponse) => { if (!pageIndex || previousPageData.has_more) @@ -24,11 +27,10 @@ const Apps = () => { const { isCurrentWorkspaceManager } = useAppContext() const { data, isLoading, setSize, mutate } = useSWRInfinite(getKey, fetchAppList, { revalidateFirstPage: false }) const anchorRef = useRef(null) - const searchParams = useSearchParams() const router = useRouter() - const payProviderName = searchParams.get('provider_name') - const payStatus = searchParams.get('payment_result') - const [showPayStatusModal, setShowPayStatusModal] = useState(false) + const [showPayStatusModal, setShowPayStatusModal] = useState(true) + const anthropicConfirmInfo = useAnthropicCheckPay() + const sparkConfirmInfo = useSparkCheckQuota() const handleCancelShowPayStatusModal = useCallback(() => { setShowPayStatusModal(false) @@ -41,9 +43,7 @@ const Apps = () => { localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY) mutate() } - if (payProviderName === ProviderEnum.anthropic && (payStatus === 'succeeded' || payStatus === 'cancelled')) - setShowPayStatusModal(true) - }, [mutate, payProviderName, payStatus, t]) + }, [mutate, t]) useEffect(() => { let observer: IntersectionObserver | undefined @@ -65,23 +65,29 @@ const Apps = () => { )))} { - showPayStatusModal && ( + showPayStatusModal && anthropicConfirmInfo && ( + ) + } + { + showPayStatusModal && sparkConfirmInfo && ( + ) } diff --git a/web/app/components/app/chat/citation/popup.tsx b/web/app/components/app/chat/citation/popup.tsx index 7feb823bbb..20e04df63f 100644 --- a/web/app/components/app/chat/citation/popup.tsx +++ b/web/app/components/app/chat/citation/popup.tsx @@ -75,7 +75,7 @@ const Popup: FC = ({ - Link to dataset + {t('common.chat.citation.linkToDataset')} diff --git a/web/app/components/base/confirm/common.tsx b/web/app/components/base/confirm/common.tsx index f2c8776cbf..282ff422f3 100644 --- a/web/app/components/base/confirm/common.tsx +++ b/web/app/components/base/confirm/common.tsx @@ -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 Button from '@/app/components/base/button' -type ConfirmCommonProps = { +export type ConfirmCommonProps = { type?: string isShow: boolean onCancel: () => void diff --git a/web/hooks/use-pay.ts b/web/hooks/use-pay.ts new file mode 100644 index 0000000000..011d0d6a17 --- /dev/null +++ b/web/hooks/use-pay.ts @@ -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 + +export const useAnthropicCheckPay = () => { + const { t } = useTranslation() + const [confirm, setConfirm] = useState(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 +} diff --git a/web/i18n/lang/common.zh.ts b/web/i18n/lang/common.zh.ts index 6da80c815c..50631276a3 100644 --- a/web/i18n/lang/common.zh.ts +++ b/web/i18n/lang/common.zh.ts @@ -345,7 +345,7 @@ const translation = { conversationNameCanNotEmpty: '会话名称必填', citation: { title: '引用', - linkToDataset: '去往数据集', + linkToDataset: '跳转至数据集', characters: '字符:', hitCount: '命中次数:', vectorHash: '向量哈希:', diff --git a/web/service/common.ts b/web/service/common.ts index 3bdff8dcda..18bbc99167 100644 --- a/web/service/common.ts +++ b/web/service/common.ts @@ -184,3 +184,7 @@ export const fetchFileUploadConfig: Fetcher = (url) => { return get(url) as Promise } + +export const fetchSparkFreeQuotaVerify: Fetcher<{ result: string; flag: boolean; reason: string }, string> = (url) => { + return get(url) as Promise<{ result: string; flag: boolean; reason: string }> +}