Some checks failed
Deploy Admin Frontend / build-and-deploy (push) Failing after 0s
31 lines
2.1 KiB
TypeScript
31 lines
2.1 KiB
TypeScript
import { useState } from 'react'
|
|
import { useQuery, useQueryClient } from '@tanstack/react-query'
|
|
import { Card, Row, Col, Statistic, Button, Tag, Space, Typography, App } from 'antd'
|
|
import { DollarOutlined, ReloadOutlined, LinkOutlined } from '@ant-design/icons'
|
|
import { getBilling, type BillingInfo } from '@/services/billing-api'
|
|
const { Text } = Typography
|
|
function BillingCard({ p }: { p: BillingInfo }) {
|
|
const color = p.status === 'ok' ? (parseFloat(p.balance) < 10 ? '#faad14' : '#52c41a') : '#999'
|
|
return (
|
|
<Card title={<Space><DollarOutlined />{p.name}<Tag color={p.status === 'ok' ? 'green' : 'default'}>{p.status === 'ok' ? '正常' : '未知'}</Tag></Space>}
|
|
extra={<Button type="link" size="small" icon={<LinkOutlined />} href={p.consoleUrl} target="_blank">控制台</Button>}>
|
|
<Statistic title="余额" value={p.balance} valueStyle={{ color, fontSize: 28 }} suffix={<Text type="secondary" style={{ fontSize: 14 }}>{p.currency}</Text>} />
|
|
<div style={{ marginTop: 8 }}><Text type="secondary" style={{ fontSize: 12 }}>模型: {p.model}</Text><br /><Text type="secondary" style={{ fontSize: 12 }}>{p.note}</Text></div>
|
|
</Card>
|
|
)
|
|
}
|
|
function BillingContent() {
|
|
const qc = useQueryClient(); const [refreshing, setRefreshing] = useState(false)
|
|
const { data } = useQuery({ queryKey: ['billing'], queryFn: getBilling, staleTime: 60_000 })
|
|
return (
|
|
<div>
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 16 }}>
|
|
<Typography.Title level={5} style={{ margin: 0 }}><DollarOutlined /> API 用量</Typography.Title>
|
|
<Button icon={<ReloadOutlined spin={refreshing} />} onClick={async () => { setRefreshing(true); await qc.invalidateQueries({ queryKey: ['billing'] }); setTimeout(() => setRefreshing(false), 800) }} loading={refreshing}>刷新</Button>
|
|
</div>
|
|
<Row gutter={[16, 16]}>{(data?.providers || []).map(p => <Col xs={24} sm={12} lg={6} key={p.name}><BillingCard p={p} /></Col>)}</Row>
|
|
</div>
|
|
)
|
|
}
|
|
export default function BillingPage() { return <App><BillingContent /></App> }
|