Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion controller/subscription_payment_epay.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ func SubscriptionRequestEpay(c *gin.Context) {
common.ApiErrorMsg(c, "拉起支付失败")
return
}
common.ApiSuccess(c, gin.H{"data": params, "url": uri})
c.JSON(http.StatusOK, gin.H{"message": "success", "data": params, "url": uri})
}

func SubscriptionEpayNotify(c *gin.Context) {
Expand Down
108 changes: 63 additions & 45 deletions web/src/components/topup/SubscriptionPlansCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ const SubscriptionPlansCard = ({
showSuccess(t('已打开支付页面'));
closeBuy();
} else {
showError(res.data?.data || res.data?.message || t('支付失败'));
const errorMsg =
typeof res.data?.data === 'string'
? res.data.data
: res.data?.message || t('支付失败');
showError(errorMsg);
}
} catch (e) {
showError(t('支付请求失败'));
Expand All @@ -152,7 +156,11 @@ const SubscriptionPlansCard = ({
showSuccess(t('已打开支付页面'));
closeBuy();
} else {
showError(res.data?.data || res.data?.message || t('支付失败'));
const errorMsg =
typeof res.data?.data === 'string'
? res.data.data
: res.data?.message || t('支付失败');
showError(errorMsg);
}
} catch (e) {
showError(t('支付请求失败'));
Expand All @@ -177,7 +185,11 @@ const SubscriptionPlansCard = ({
showSuccess(t('已发起支付'));
closeBuy();
} else {
showError(res.data?.data || res.data?.message || t('支付失败'));
const errorMsg =
typeof res.data?.data === 'string'
? res.data.data
: res.data?.message || t('支付失败');
showError(errorMsg);
}
} catch (e) {
showError(t('支付请求失败'));
Expand Down Expand Up @@ -269,9 +281,13 @@ const SubscriptionPlansCard = ({
</div>
</Card>
{/* 套餐列表骨架屏 */}
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4'>
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-5 w-full'>
{[1, 2, 3].map((i) => (
<Card key={i} className='!rounded-xl' bodyStyle={{ padding: 16 }}>
<Card
key={i}
className='!rounded-xl w-full h-full'
bodyStyle={{ padding: 16 }}
>
<Skeleton.Title
active
style={{ width: '60%', height: 24, marginBottom: 8 }}
Expand Down Expand Up @@ -435,7 +451,7 @@ const SubscriptionPlansCard = ({

{/* 可购买套餐 - 标准定价卡片 */}
{plans.length > 0 ? (
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-4'>
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-2 xl:grid-cols-3 gap-5 w-full'>
{plans.map((p, index) => {
const plan = p?.plan;
const totalAmount = Number(plan?.total_amount || 0);
Expand Down Expand Up @@ -477,23 +493,23 @@ const SubscriptionPlansCard = ({
return (
<Card
key={plan?.id}
className={`!rounded-xl transition-all hover:shadow-lg ${
className={`!rounded-xl transition-all hover:shadow-lg w-full h-full ${
isPopular ? 'ring-2 ring-purple-500' : ''
}`}
bodyStyle={{ padding: 0 }}
>
<div className='p-4'>
<div className='p-4 h-full flex flex-col'>
{/* 推荐标签 */}
{isPopular && (
<div className='text-center mb-2'>
<div className='mb-2'>
<Tag color='purple' shape='circle' size='small'>
<Sparkles size={10} className='mr-1' />
{t('推荐')}
</Tag>
</div>
)}
{/* 套餐名称 */}
<div className='text-center mb-3'>
<div className='mb-3'>
<Typography.Title
heading={5}
ellipsis={{ rows: 1, showTooltip: true }}
Expand All @@ -514,8 +530,8 @@ const SubscriptionPlansCard = ({
</div>

{/* 价格区域 */}
<div className='text-center py-2'>
<div className='flex items-baseline justify-center'>
<div className='py-2'>
<div className='flex items-baseline justify-start'>
<span className='text-xl font-bold text-purple-600'>
{symbol}
</span>
Expand All @@ -526,7 +542,7 @@ const SubscriptionPlansCard = ({
</div>

{/* 套餐权益描述 */}
<div className='flex flex-col items-center gap-1 pb-2'>
<div className='flex flex-col items-start gap-1 pb-2'>
{planBenefits.map((item) => {
const content = (
<div className='flex items-center gap-2 text-xs text-gray-500'>
Expand All @@ -538,52 +554,54 @@ const SubscriptionPlansCard = ({
return (
<div
key={item.label}
className='w-full flex justify-center'
className='w-full flex justify-start'
>
{content}
</div>
);
}
return (
<Tooltip key={item.label} content={item.tooltip}>
<div className='w-full flex justify-center'>
<div className='w-full flex justify-start'>
{content}
</div>
</Tooltip>
);
})}
</div>

<Divider margin={12} />

{/* 购买按钮 */}
{(() => {
const count = getPlanPurchaseCount(p?.plan?.id);
const reached = limit > 0 && count >= limit;
const tip = reached
? t('已达到购买上限') + ` (${count}/${limit})`
: '';
const buttonEl = (
<Button
theme='outline'
type='tertiary'
block
disabled={reached}
onClick={() => {
if (!reached) openBuy(p);
}}
>
{reached ? t('已达上限') : t('立即订阅')}
</Button>
);
return reached ? (
<Tooltip content={tip} position='top'>
{buttonEl}
</Tooltip>
) : (
buttonEl
);
})()}
<div className='mt-auto'>
<Divider margin={12} />

{/* 购买按钮 */}
{(() => {
const count = getPlanPurchaseCount(p?.plan?.id);
const reached = limit > 0 && count >= limit;
const tip = reached
? t('已达到购买上限') + ` (${count}/${limit})`
: '';
const buttonEl = (
<Button
theme='outline'
type='tertiary'
block
disabled={reached}
onClick={() => {
if (!reached) openBuy(p);
}}
>
{reached ? t('已达上限') : t('立即订阅')}
</Button>
);
return reached ? (
<Tooltip content={tip} position='top'>
{buttonEl}
</Tooltip>
) : (
buttonEl
);
})()}
</div>
</div>
</Card>
);
Expand Down
8 changes: 6 additions & 2 deletions web/src/components/topup/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,9 @@ const TopUp = () => {
document.body.removeChild(form);
}
} else {
showError(data);
const errorMsg =
typeof data === 'string' ? data : message || t('支付失败');
showError(errorMsg);
}
} else {
showError(res);
Expand Down Expand Up @@ -293,7 +295,9 @@ const TopUp = () => {
if (message === 'success') {
processCreemCallback(data);
} else {
showError(data);
const errorMsg =
typeof data === 'string' ? data : message || t('支付失败');
showError(errorMsg);
}
} else {
showError(res);
Expand Down
28 changes: 14 additions & 14 deletions web/src/helpers/render.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -170,30 +170,30 @@ export const getModelCategories = (() => {
gemini: {
label: 'Gemini',
icon: <Gemini.Color />,
filter: (model) =>
model.model_name.toLowerCase().includes('gemini') ||
filter: (model) =>
model.model_name.toLowerCase().includes('gemini') ||
model.model_name.toLowerCase().includes('gemma') ||
model.model_name.toLowerCase().includes('learnlm') ||
model.model_name.toLowerCase().includes('learnlm') ||
model.model_name.toLowerCase().startsWith('embedding-') ||
model.model_name.toLowerCase().includes('text-embedding-004') ||
model.model_name.toLowerCase().includes('imagen-4') ||
model.model_name.toLowerCase().includes('veo-') ||
model.model_name.toLowerCase().includes('aqa') ,
model.model_name.toLowerCase().includes('imagen-4') ||
model.model_name.toLowerCase().includes('veo-') ||
model.model_name.toLowerCase().includes('aqa'),
},
moonshot: {
label: 'Moonshot',
icon: <Moonshot />,
filter: (model) =>
model.model_name.toLowerCase().includes('moonshot') ||
filter: (model) =>
model.model_name.toLowerCase().includes('moonshot') ||
model.model_name.toLowerCase().includes('kimi'),
},
zhipu: {
label: t('智谱'),
icon: <Zhipu.Color />,
filter: (model) =>
model.model_name.toLowerCase().includes('chatglm') ||
model.model_name.toLowerCase().includes('glm-') ||
model.model_name.toLowerCase().includes('cogview') ||
model.model_name.toLowerCase().includes('glm-') ||
model.model_name.toLowerCase().includes('cogview') ||
model.model_name.toLowerCase().includes('cogvideo'),
},
qwen: {
Expand All @@ -209,8 +209,8 @@ export const getModelCategories = (() => {
minimax: {
label: 'MiniMax',
icon: <Minimax.Color />,
filter: (model) =>
model.model_name.toLowerCase().includes('abab') ||
filter: (model) =>
model.model_name.toLowerCase().includes('abab') ||
model.model_name.toLowerCase().includes('minimax'),
},
baidu: {
Expand All @@ -236,7 +236,7 @@ export const getModelCategories = (() => {
cohere: {
label: 'Cohere',
icon: <Cohere.Color />,
filter: (model) =>
filter: (model) =>
model.model_name.toLowerCase().includes('command') ||
model.model_name.toLowerCase().includes('c4ai-') ||
model.model_name.toLowerCase().includes('embed-'),
Expand All @@ -259,7 +259,7 @@ export const getModelCategories = (() => {
mistral: {
label: 'Mistral AI',
icon: <Mistral.Color />,
filter: (model) =>
filter: (model) =>
model.model_name.toLowerCase().includes('mistral') ||
model.model_name.toLowerCase().includes('codestral') ||
model.model_name.toLowerCase().includes('pixtral') ||
Expand Down