소스 검색

fix: free quota tip (#831)

zxhlyh 1 년 전
부모
커밋
0feb0bf7c0

+ 1 - 10
web/app/(commonLayout)/apps/Apps.tsx

@@ -4,13 +4,12 @@ import { useEffect, useRef } from 'react'
 import useSWRInfinite from 'swr/infinite'
 import { debounce } from 'lodash-es'
 import { useTranslation } from 'react-i18next'
-import { useSearchParams } from 'next/navigation'
 import AppCard from './AppCard'
 import NewAppCard from './NewAppCard'
 import type { AppListResponse } from '@/models/app'
 import { fetchAppList } from '@/service/apps'
 import { useSelector } from '@/context/app-context'
-import { NEED_REFRESH_APP_LIST_KEY, SPARK_FREE_QUOTA_PENDING } from '@/config'
+import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
 
 const getKey = (pageIndex: number, previousPageData: AppListResponse) => {
   if (!pageIndex || previousPageData.has_more)
@@ -24,7 +23,6 @@ const Apps = () => {
   const loadingStateRef = useRef(false)
   const pageContainerRef = useSelector(state => state.pageContainerRef)
   const anchorRef = useRef<HTMLAnchorElement>(null)
-  const searchParams = useSearchParams()
 
   useEffect(() => {
     document.title = `${t('app.title')} -  Dify`
@@ -32,13 +30,6 @@ const Apps = () => {
       localStorage.removeItem(NEED_REFRESH_APP_LIST_KEY)
       mutate()
     }
-    if (
-      localStorage.getItem(SPARK_FREE_QUOTA_PENDING) !== '1'
-      && searchParams.get('type') === 'provider_apply_callback'
-      && searchParams.get('provider') === 'spark'
-      && searchParams.get('result') === 'success'
-    )
-      localStorage.setItem(SPARK_FREE_QUOTA_PENDING, '1')
   }, [])
 
   useEffect(() => {

+ 5 - 0
web/app/components/base/icons/assets/vender/line/general/link-external-01.svg

@@ -0,0 +1,5 @@
+<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
+<g id="link-external-01">
+<path id="Icon" d="M10.5 4.5L10.5 1.5M10.5 1.5H7.5M10.5 1.5L6.5 5.5M5 2.5H3.9C3.05992 2.5 2.63988 2.5 2.31901 2.66349C2.03677 2.8073 1.8073 3.03677 1.66349 3.31901C1.5 3.63988 1.5 4.05992 1.5 4.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5H7.1C7.94008 10.5 8.36012 10.5 8.68099 10.3365C8.96323 10.1927 9.1927 9.96323 9.33651 9.68099C9.5 9.36012 9.5 8.94008 9.5 8.1V7" stroke="#155EEF" stroke-linecap="round" stroke-linejoin="round"/>
+</g>
+</svg>

+ 38 - 0
web/app/components/base/icons/src/vender/line/general/LinkExternal01.json

@@ -0,0 +1,38 @@
+{
+	"icon": {
+		"type": "element",
+		"isRootNode": true,
+		"name": "svg",
+		"attributes": {
+			"width": "12",
+			"height": "12",
+			"viewBox": "0 0 12 12",
+			"fill": "none",
+			"xmlns": "http://www.w3.org/2000/svg"
+		},
+		"children": [
+			{
+				"type": "element",
+				"name": "g",
+				"attributes": {
+					"id": "link-external-01"
+				},
+				"children": [
+					{
+						"type": "element",
+						"name": "path",
+						"attributes": {
+							"id": "Icon",
+							"d": "M10.5 4.5L10.5 1.5M10.5 1.5H7.5M10.5 1.5L6.5 5.5M5 2.5H3.9C3.05992 2.5 2.63988 2.5 2.31901 2.66349C2.03677 2.8073 1.8073 3.03677 1.66349 3.31901C1.5 3.63988 1.5 4.05992 1.5 4.9V8.1C1.5 8.94008 1.5 9.36012 1.66349 9.68099C1.8073 9.96323 2.03677 10.1927 2.31901 10.3365C2.63988 10.5 3.05992 10.5 3.9 10.5H7.1C7.94008 10.5 8.36012 10.5 8.68099 10.3365C8.96323 10.1927 9.1927 9.96323 9.33651 9.68099C9.5 9.36012 9.5 8.94008 9.5 8.1V7",
+							"stroke": "currentColor",
+							"stroke-linecap": "round",
+							"stroke-linejoin": "round"
+						},
+						"children": []
+					}
+				]
+			}
+		]
+	},
+	"name": "LinkExternal01"
+}

+ 14 - 0
web/app/components/base/icons/src/vender/line/general/LinkExternal01.tsx

@@ -0,0 +1,14 @@
+// GENERATE BY script
+// DON NOT EDIT IT MANUALLY
+
+import * as React from 'react'
+import data from './LinkExternal01.json'
+import IconBase from '@/app/components/base/icons/IconBase'
+import type { IconBaseProps, IconData } from '@/app/components/base/icons/IconBase'
+
+const Icon = React.forwardRef<React.MutableRefObject<SVGElement>, Omit<IconBaseProps, 'data'>>((
+  props,
+  ref,
+) => <IconBase {...props} ref={ref} data={data as IconData} />)
+
+export default Icon

+ 1 - 0
web/app/components/base/icons/src/vender/line/general/index.ts

@@ -5,6 +5,7 @@ export { default as Edit03 } from './Edit03'
 export { default as Hash02 } from './Hash02'
 export { default as HelpCircle } from './HelpCircle'
 export { default as InfoCircle } from './InfoCircle'
+export { default as LinkExternal01 } from './LinkExternal01'
 export { default as LinkExternal02 } from './LinkExternal02'
 export { default as Loading02 } from './Loading02'
 export { default as LogOut01 } from './LogOut01'

+ 13 - 38
web/app/components/header/account-setting/model-page/model-item/FreeQuota.tsx

@@ -1,14 +1,14 @@
-import { useEffect, useState } from 'react'
+import { useState } from 'react'
 import type { FC } from 'react'
 import { useTranslation } from 'react-i18next'
 import { useContext } from 'use-context-selector'
-import type { ProviderConfigItem, ProviderWithQuota, TypeWithI18N } from '../declarations'
+import type { ProviderConfigItem, TypeWithI18N } from '../declarations'
 import { ProviderEnum as ProviderEnumValue } from '../declarations'
 import s from './index.module.css'
 import I18n from '@/context/i18n'
 import Button from '@/app/components/base/button'
 import { submitFreeQuota } from '@/service/common'
-import { SPARK_FREE_QUOTA_PENDING } from '@/config'
+import { LinkExternal01 } from '@/app/components/base/icons/src/vender/line/general'
 
 const TIP_MAP: { [k: string]: TypeWithI18N } = {
   [ProviderEnumValue.minimax]: {
@@ -20,34 +20,17 @@ const TIP_MAP: { [k: string]: TypeWithI18N } = {
     'zh-Hans': '免费获取 300 万个 token',
   },
 }
-const FREE_QUOTA_TIP = {
-  'en': 'Your 3 million tokens will be credited in 5 minutes.',
-  'zh-Hans': '您的 300 万 token 将在 5 分钟内到账。',
-}
 type FreeQuotaProps = {
   modelItem: ProviderConfigItem
   onUpdate: () => void
-  freeProvider?: ProviderWithQuota
 }
 const FreeQuota: FC<FreeQuotaProps> = ({
   modelItem,
   onUpdate,
-  freeProvider,
 }) => {
   const { locale } = useContext(I18n)
   const { t } = useTranslation()
   const [loading, setLoading] = useState(false)
-  const [freeQuotaPending, setFreeQuotaPending] = useState(false)
-
-  useEffect(() => {
-    if (
-      modelItem.key === ProviderEnumValue.spark
-      && localStorage.getItem(SPARK_FREE_QUOTA_PENDING) === '1'
-      && freeProvider
-      && !freeProvider.is_valid
-    )
-      setFreeQuotaPending(true)
-  }, [freeProvider, modelItem.key])
 
   const handleClick = async () => {
     try {
@@ -64,29 +47,21 @@ const FreeQuota: FC<FreeQuotaProps> = ({
     }
   }
 
-  if (freeQuotaPending) {
-    return (
-      <div className='flex items-center'>
-        ⏳
-        <div className={`${s.vender} ml-1 mr-2 text-xs font-medium text-transparent`}>{FREE_QUOTA_TIP[locale]}</div>
-        <Button
-          className='!px-3 !h-7 !rounded-md !text-xs !font-medium !bg-white !text-gray-700'
-          onClick={onUpdate}
-        >
-          {t('common.operation.reload')}
-        </Button>
-        <div className='mx-2 w-[1px] h-4 bg-black/5' />
-      </div>
-    )
-  }
-
   return (
     <div className='flex items-center'>
       📣
-      <div className={`${s.vender} ml-1 mr-2 text-xs font-medium text-transparent`}>{TIP_MAP[modelItem.key][locale]}</div>
+      <div className={`${s.vender} ml-1 text-xs font-medium text-transparent`}>{TIP_MAP[modelItem.key][locale]}</div>
+      <div className='mx-1 text-xs font-medium text-gray-400'>·</div>
+      <a
+        href='https://docs.dify.ai/v/zh-hans/getting-started/faq/llms-use-faq#8.-ru-he-mian-fei-shen-ling-xun-fei-xing-huo-minimax-mo-xing-de-ti-yanedu'
+        target='_blank'
+        className='flex items-center text-xs font-medium text-[#155EEF]'>
+        {t('common.modelProvider.freeQuota.howToEarn')}
+        <LinkExternal01 className='ml-0.5 w-3 h-3' />
+      </a>
       <Button
         type='primary'
-        className='!px-3 !h-7 !rounded-md !text-xs !font-medium'
+        className='ml-3 !px-3 !h-7 !rounded-md !text-xs !font-medium'
         onClick={handleClick}
         disabled={loading}
       >

+ 1 - 2
web/app/components/header/account-setting/model-page/model-item/Setting.tsx

@@ -34,10 +34,9 @@ const Setting: FC<SettingProps> = ({
   return (
     <div className='flex items-center'>
       {
-        (modelItem.key === ProviderEnum.minimax || modelItem.key === ProviderEnum.spark) && systemFree && !systemFree?.is_valid && !IS_CE_EDITION && (
+        (modelItem.key === ProviderEnum.minimax || modelItem.key === ProviderEnum.spark) && systemFree && !systemFree?.is_valid && !IS_CE_EDITION && locale === 'zh-Hans' && (
           <FreeQuota
             modelItem={modelItem}
-            freeProvider={systemFree}
             onUpdate={onUpdate}
           />
         )

+ 0 - 1
web/config/index.ts

@@ -120,4 +120,3 @@ export const VAR_ITEM_TEMPLATE = {
 export const appDefaultIconBackground = '#D5F5F6'
 
 export const NEED_REFRESH_APP_LIST_KEY = 'needRefreshAppList'
-export const SPARK_FREE_QUOTA_PENDING = 'sparkFreeQuotaPending'

+ 3 - 0
web/i18n/lang/common.en.ts

@@ -250,6 +250,9 @@ const translation = {
       front: 'Your API KEY will be encrypted and stored using',
       back: ' technology.',
     },
+    freeQuota: {
+      howToEarn: 'How to earn',
+    },
   },
   dataSource: {
     add: 'Add a data source',

+ 3 - 0
web/i18n/lang/common.zh.ts

@@ -250,6 +250,9 @@ const translation = {
       front: '您的密钥将使用',
       back: '技术进行加密和存储。',
     },
+    freeQuota: {
+      howToEarn: '如何获取',
+    },
   },
   dataSource: {
     add: '添加数据源',