fix: connect remaining sms pages to real backend

This commit is contained in:
hectorzhao
2026-07-02 19:30:04 +08:00
parent 06562e42dd
commit 131f344ac4
50 changed files with 2074 additions and 6400 deletions
+30 -8
View File
@@ -1,9 +1,28 @@
import { useEffect, useState } from 'react';
import { CreditCard } from 'lucide-react';
import { Button, Tag } from '@/components/ui';
import { clientService } from '@/mock';
import { clientApi, type BillingPlan } from '@/api/adminApi';
export function ClientBillingPage() {
const plans = clientService.getBillingPlans();
const [plans, setPlans] = useState<BillingPlan[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState('');
useEffect(() => {
setLoading(true);
clientApi.listPlans()
.then((items) => {
setPlans(items.filter((item) => item.status !== 'disabled' && item.status !== 'deleted'));
setError('');
})
.catch((reason: Error) => setError(reason.message || '充值套餐加载失败'))
.finally(() => setLoading(false));
}, []);
function createOrder(plan: BillingPlan) {
clientApi.createOrder({ planId: plan.id, amountCents: plan.amountCents, smsUnits: plan.smsUnits, payMethod: 'manual' })
.catch((reason: Error) => setError(reason.message || '充值订单创建失败'));
}
return (
<section className="page-stack">
@@ -14,21 +33,24 @@ export function ClientBillingPage() {
</div>
</div>
<div className="surface">
{loading ? <p className="muted">...</p> : null}
{error ? <p className="form-error">{error}</p> : null}
<div className="plan-grid">
{plans.map((plan) => (
<article className={['plan-card', plan.highlight ? 'plan-card--highlight' : ''].filter(Boolean).join(' ')} key={plan.id}>
<article className={['plan-card', plan.smsUnits >= 100000 ? 'plan-card--highlight' : ''].filter(Boolean).join(' ')} key={plan.id}>
<div className="section-heading">
<h2>{plan.name}</h2>
{plan.highlight ? <Tag tone="accent"></Tag> : null}
{plan.smsUnits >= 100000 ? <Tag tone="accent"></Tag> : null}
</div>
<strong>{plan.messages.toLocaleString('zh-CN')} </strong>
<p className="muted"></p>
<Button icon={<CreditCard size={16} />} variant={plan.highlight ? 'primary' : 'ghost'}>
¥{plan.price.toLocaleString('zh-CN')}
<strong>{plan.smsUnits.toLocaleString('zh-CN')} </strong>
<p className="muted">{plan.description ?? '适合阶段性短信发送和活动通知。'}</p>
<Button icon={<CreditCard size={16} />} onClick={() => createOrder(plan)} variant={plan.smsUnits >= 100000 ? 'primary' : 'ghost'}>
¥{(plan.amountCents / 100).toLocaleString('zh-CN')}
</Button>
</article>
))}
</div>
{!loading && !error && plans.length === 0 ? <p className="muted"></p> : null}
</div>
</section>
);