revert: remove billing page — already exists in existing panel
Some checks failed
Deploy Admin Frontend / build-and-deploy (push) Failing after 6s

This commit is contained in:
WangDL 2026-05-22 15:27:43 +08:00
parent 3d8bc4b9d7
commit 7fc169b3f7
3 changed files with 3 additions and 77 deletions

View File

@ -1,8 +1,9 @@
import type React from 'react'
import { CodeOutlined, CloudServerOutlined, RobotOutlined, DashboardOutlined, DollarOutlined,
import { DollarOutlined, CodeOutlined, CloudServerOutlined, RobotOutlined, DashboardOutlined,
UserOutlined,
BookOutlined,
ImportOutlined,
DollarOutlined,
SettingOutlined,
FileOutlined,
CloudOutlined,
@ -32,6 +33,7 @@ export const adminMenuItems: AdminMenuItem[] = [
{ path: '/users/members', name: '普通用户' },
],
},
{ path: '/membership', name: '会员与额度', icon: <DollarOutlined />, requiredRole: 'ADMIN' },
{
path: '/knowledge',
name: '知识库管理',

View File

@ -1,61 +0,0 @@
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' ? (p.currency === 'CNY' && 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,
})
const refresh = async () => {
setRefreshing(true)
await qc.invalidateQueries({ queryKey: ['billing'] })
setTimeout(() => setRefreshing(false), 800)
}
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={refresh} 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>
}

View File

@ -1,15 +0,0 @@
import { api } from './http-client'
export interface BillingInfo {
name: string
model: string
balance: string
currency: string
status: 'ok' | 'unknown'
consoleUrl: string
note: string
}
export function getBilling(): Promise<{ providers: BillingInfo[] }> {
return api.get('/admin-api/billing')
}