Ver a proveniência

feat(home): 首页定价卡片添加"去体验"按钮,跳转 Playground

- PricingCardView 新增 showTryButton 属性,点击跳转 Playground 并预选模型
- 移除 PricingCardView 中未使用的 props (selectedGroup, currency 等)
- 首页页脚路由重命名: terms→user-agreement, usage-policy→privacy-policy
- i18n: "操练场"更名为"对话"

Co-Authored-By: Claude <noreply@anthropic.com>
master
fengsilin há 1 semana
ascendente
cometimento
8bb2883d7e
7 ficheiros alterados com 30 adições e 49 eliminações
  1. +2
    -2
      web/src/App.jsx
  2. +19
    -19
      web/src/components/table/model-pricing/view/card/PricingCardView.jsx
  3. +0
    -17
      web/src/hooks/model-pricing/useModelPricingData.jsx
  4. +3
    -2
      web/src/i18n/locales/en.json
  5. +3
    -2
      web/src/i18n/locales/zh-CN.json
  6. +1
    -5
      web/src/pages/Home/HomePricingFilters.jsx
  7. +2
    -2
      web/src/pages/Home/components/HomePageFooter.jsx

+ 2
- 2
web/src/App.jsx Ver ficheiro

@@ -361,7 +361,7 @@ function App() {
} }
/> />
<Route <Route
path='/terms'
path='/user-agreement'
element={ element={
<Suspense fallback={<Loading></Loading>} key={location.pathname}> <Suspense fallback={<Loading></Loading>} key={location.pathname}>
<Terms /> <Terms />
@@ -369,7 +369,7 @@ function App() {
} }
/> />
<Route <Route
path='/usage-policy'
path='/privacy-policy'
element={ element={
<Suspense fallback={<Loading></Loading>} key={location.pathname}> <Suspense fallback={<Loading></Loading>} key={location.pathname}>
<UsagePolicy /> <UsagePolicy />


+ 19
- 19
web/src/components/table/model-pricing/view/card/PricingCardView.jsx Ver ficheiro

@@ -18,6 +18,7 @@ For commercial licensing, please contact support@quantumnous.com
*/ */


import React from 'react'; import React from 'react';
import { useNavigate } from 'react-router-dom';
import { import {
Card, Card,
Tag, Tag,
@@ -36,8 +37,6 @@ import {
} from '@douyinfe/semi-illustrations'; } from '@douyinfe/semi-illustrations';
import { import {
stringToColor, stringToColor,
calculateModelPrice,
formatPriceInfo,
getLobeHubIcon, getLobeHubIcon,
} from '../../../../../helpers'; } from '../../../../../helpers';
import PricingCardSkeleton from './PricingCardSkeleton'; import PricingCardSkeleton from './PricingCardSkeleton';
@@ -61,14 +60,9 @@ const PricingCardView = ({
setPageSize, setPageSize,
currentPage, currentPage,
setCurrentPage, setCurrentPage,
selectedGroup,
groupRatio,
copyText, copyText,
setModalImageUrl, setModalImageUrl,
setIsModalOpenurl, setIsModalOpenurl,
currency,
tokenUnit,
displayPrice,
showRatio, showRatio,
t, t,
selectedRowKeys = [], selectedRowKeys = [],
@@ -76,6 +70,7 @@ const PricingCardView = ({
openModelDetail, openModelDetail,
gridColsClass = 'grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3', gridColsClass = 'grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3',
showPagination = true, showPagination = true,
showTryButton = false,
}) => { }) => {
const showSkeleton = useMinimumLoadingTime(loading); const showSkeleton = useMinimumLoadingTime(loading);
const startIndex = (currentPage - 1) * pageSize; const startIndex = (currentPage - 1) * pageSize;
@@ -84,6 +79,7 @@ const PricingCardView = ({
: filteredModels; : filteredModels;
const getModelKey = (model) => model.key ?? model.model_name ?? model.id; const getModelKey = (model) => model.key ?? model.model_name ?? model.id;
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const navigate = useNavigate();


const handleCheckboxChange = (model, checked) => { const handleCheckboxChange = (model, checked) => {
if (!setSelectedRowKeys) return; if (!setSelectedRowKeys) return;
@@ -240,15 +236,6 @@ const PricingCardView = ({
const modelKey = getModelKey(model); const modelKey = getModelKey(model);
const isSelected = selectedRowKeys.includes(modelKey); const isSelected = selectedRowKeys.includes(modelKey);


const priceData = calculateModelPrice({
record: model,
selectedGroup,
groupRatio,
tokenUnit,
displayPrice,
currency,
});

return ( return (
<Card <Card
key={modelKey || index} key={modelKey || index}
@@ -265,9 +252,6 @@ const PricingCardView = ({
<h3 className='text-lg font-bold text-gray-900 break-all'> <h3 className='text-lg font-bold text-gray-900 break-all'>
{model.model_name} {model.model_name}
</h3> </h3>
<div className='text-xs mt-1'>
{formatPriceInfo(priceData, t)}
</div>
</div> </div>
</div> </div>


@@ -324,6 +308,22 @@ const PricingCardView = ({
</Tag> </Tag>
)} )}


{/* 去体验按钮 */}
{showTryButton && (
<Button
size='small'
theme='solid'
type='primary'
style={{ marginTop: 8, width: '100%' }}
onClick={(e) => {
e.stopPropagation();
navigate('/console/playground?model=' + encodeURIComponent(model.model_name));
}}
>
{t('去体验')} →
</Button>
)}

{/* 倍率信息(可选) */} {/* 倍率信息(可选) */}
{showRatio && ( {showRatio && (
<div className='pt-3'> <div className='pt-3'>


+ 0
- 17
web/src/hooks/model-pricing/useModelPricingData.jsx Ver ficheiro

@@ -206,23 +206,6 @@ export const useModelPricingData = () => {
m.vendor_description = vendor.description; m.vendor_description = vendor.description;
} }
} }
models.sort((a, b) => {
return a.quota_type - b.quota_type;
});

models.sort((a, b) => {
if (a.model_name.startsWith('gpt') && !b.model_name.startsWith('gpt')) {
return -1;
} else if (
!a.model_name.startsWith('gpt') &&
b.model_name.startsWith('gpt')
) {
return 1;
} else {
return a.model_name.localeCompare(b.model_name);
}
});

setModels(models); setModels(models);
}; };




+ 3
- 2
web/src/i18n/locales/en.json Ver ficheiro

@@ -1365,8 +1365,8 @@
"操作成功完成!": "Operation completed successfully!", "操作成功完成!": "Operation completed successfully!",
"操作暂时被禁用": "Operation temporarily disabled", "操作暂时被禁用": "Operation temporarily disabled",
"操作确认": "Operation confirmation", "操作确认": "Operation confirmation",
"操练场": "Playground",
"操练场和聊天功能": "Playground and chat functions",
"操练场": "Chat",
"操练场和聊天功能": "Chat functions",
"支付": "Pay", "支付": "Pay",
"支付地址": "Payment address", "支付地址": "Payment address",
"支付失败": "Payment failed", "支付失败": "Payment failed",
@@ -3081,6 +3081,7 @@
"高级设置": "Advanced Settings", "高级设置": "Advanced Settings",
"高级配置": "Advanced Configuration", "高级配置": "Advanced Configuration",
"黑名单": "Blacklist", "黑名单": "Blacklist",
"去体验": "Try it",
"默认": "Default", "默认": "Default",
"默认 API 版本": "Default API Version", "默认 API 版本": "Default API Version",
"默认 Responses API 版本,为空则使用上方版本": "Default Responses API version, if empty, uses the version above", "默认 Responses API 版本,为空则使用上方版本": "Default Responses API version, if empty, uses the version above",


+ 3
- 2
web/src/i18n/locales/zh-CN.json Ver ficheiro

@@ -1349,8 +1349,8 @@
"操作成功完成!": "操作成功完成!", "操作成功完成!": "操作成功完成!",
"操作暂时被禁用": "操作暂时被禁用", "操作暂时被禁用": "操作暂时被禁用",
"操作确认": "操作确认", "操作确认": "操作确认",
"操练场": "操练场",
"操练场和聊天功能": "操练场和聊天功能",
"操练场": "对话",
"操练场和聊天功能": "对话和聊天功能",
"支付": "支付", "支付": "支付",
"支付地址": "支付地址", "支付地址": "支付地址",
"支付失败": "支付失败", "支付失败": "支付失败",
@@ -3058,6 +3058,7 @@
"高级设置": "高级设置", "高级设置": "高级设置",
"高级配置": "高级配置", "高级配置": "高级配置",
"黑名单": "黑名单", "黑名单": "黑名单",
"去体验": "去体验",
"默认": "默认", "默认": "默认",
"默认 API 版本": "默认 API 版本", "默认 API 版本": "默认 API 版本",
"默认 Responses API 版本,为空则使用上方版本": "默认 Responses API 版本,为空则使用上方版本", "默认 Responses API 版本,为空则使用上方版本": "默认 Responses API 版本,为空则使用上方版本",


+ 1
- 5
web/src/pages/Home/HomePricingFilters.jsx Ver ficheiro

@@ -178,20 +178,16 @@ const HomePricingFilters = ({ t }) => {
setPageSize={pricingData.setPageSize} setPageSize={pricingData.setPageSize}
currentPage={pricingData.currentPage} currentPage={pricingData.currentPage}
setCurrentPage={pricingData.setCurrentPage} setCurrentPage={pricingData.setCurrentPage}
selectedGroup={pricingData.selectedGroup}
groupRatio={pricingData.groupRatio}
copyText={pricingData.copyText} copyText={pricingData.copyText}
setModalImageUrl={pricingData.setModalImageUrl} setModalImageUrl={pricingData.setModalImageUrl}
setIsModalOpenurl={pricingData.setIsModalOpenurl} setIsModalOpenurl={pricingData.setIsModalOpenurl}
currency={pricingData.currency}
tokenUnit={pricingData.tokenUnit}
displayPrice={pricingData.displayPrice}
showRatio={showRatio} showRatio={showRatio}
t={t} t={t}
selectedRowKeys={[]} selectedRowKeys={[]}
openModelDetail={pricingData.openModelDetail} openModelDetail={pricingData.openModelDetail}
gridColsClass='grid-cols-1 md:grid-cols-2 lg:grid-cols-3' gridColsClass='grid-cols-1 md:grid-cols-2 lg:grid-cols-3'
showPagination={true} showPagination={true}
showTryButton={true}
/> />
</div> </div>




+ 2
- 2
web/src/pages/Home/components/HomePageFooter.jsx Ver ficheiro

@@ -30,8 +30,8 @@ const HomePageFooter = () => {
const currentYear = new Date().getFullYear(); const currentYear = new Date().getFullYear();


const footerLinks = [ const footerLinks = [
{ label: t('服务条款'), href: '/terms', external: false },
{ label: t('使用政策'), href: '/usage-policy', external: false },
{ label: t('用户协议'), href: '/user-agreement', external: false },
{ label: t('隐私协议'), href: '/privacy-policy', external: false },
]; ];


return ( return (


Carregando…
Cancelar
Guardar