1
This commit is contained in:
@@ -212,8 +212,8 @@ export async function batchUpdatePaymentConfigs(configs: Record<string, string>)
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function getPaymentStats(): Promise<{
|
export async function getPaymentStats(): Promise<{
|
||||||
by_status: Record<string, { count: number; amount: number }>;
|
byStatus: Record<string, { count: number; amount: number }>;
|
||||||
today: { paid_count: number; paid_amount: number };
|
today: { paidCount: number; paidAmount: number };
|
||||||
recent: any[];
|
recent: any[];
|
||||||
}> {
|
}> {
|
||||||
return api.get('/admin/payment-stats');
|
return api.get('/admin/payment-stats');
|
||||||
|
|||||||
@@ -38,9 +38,9 @@ const AdminPaymentStats: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const columns = [
|
const columns = [
|
||||||
{ title: '订单号', dataIndex: 'order_no', key: 'order_no', width: 200 },
|
{ title: '订单号', dataIndex: 'orderNo', key: 'orderNo', width: 200 },
|
||||||
{
|
{
|
||||||
title: '支付方式', dataIndex: 'payment_method', key: 'payment_method', width: 100,
|
title: '支付方式', dataIndex: 'paymentMethod', key: 'paymentMethod', width: 100,
|
||||||
render: (m: string) => {
|
render: (m: string) => {
|
||||||
const c = methodConfig[m] || { color: 'default', label: m };
|
const c = methodConfig[m] || { color: 'default', label: m };
|
||||||
return <Tag color={c.color}>{c.label}</Tag>;
|
return <Tag color={c.color}>{c.label}</Tag>;
|
||||||
@@ -58,13 +58,13 @@ const AdminPaymentStats: React.FC = () => {
|
|||||||
return <Tag color={c.color} icon={c.icon}>{c.label}</Tag>;
|
return <Tag color={c.color} icon={c.icon}>{c.label}</Tag>;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{ title: '支付宝交易号', dataIndex: 'trade_no', key: 'trade_no', width: 200, render: (v: string) => v || '-' },
|
{ title: '支付宝交易号', dataIndex: 'tradeNo', key: 'tradeNo', width: 200, render: (v: string) => v || '-' },
|
||||||
{
|
{
|
||||||
title: '创建时间', dataIndex: 'created_at', key: 'created_at', width: 160,
|
title: '创建时间', dataIndex: 'createdAt', key: 'createdAt', width: 160,
|
||||||
render: (d: string) => <span className="date-display" style={{ color: '#94a3b8' }}>{d ? formatDate(d) : '-'}</span>,
|
render: (d: string) => <span className="date-display" style={{ color: '#94a3b8' }}>{d ? formatDate(d) : '-'}</span>,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: '支付时间', dataIndex: 'paid_at', key: 'paid_at', width: 160,
|
title: '支付时间', dataIndex: 'paidAt', key: 'paidAt', width: 160,
|
||||||
render: (d: string) => <span className="date-display" style={{ color: '#94a3b8' }}>{d ? formatDate(d) : '-'}</span>,
|
render: (d: string) => <span className="date-display" style={{ color: '#94a3b8' }}>{d ? formatDate(d) : '-'}</span>,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@@ -73,9 +73,9 @@ const AdminPaymentStats: React.FC = () => {
|
|||||||
return <div style={{ padding: 24, color: '#94a3b8' }}>加载中…</div>;
|
return <div style={{ padding: 24, color: '#94a3b8' }}>加载中…</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
const paidInfo = stats.by_status?.paid || { count: 0, amount: 0 };
|
const paidInfo = stats.byStatus?.paid || { count: 0, amount: 0 };
|
||||||
const pendingInfo = stats.by_status?.pending || { count: 0, amount: 0 };
|
const pendingInfo = stats.byStatus?.pending || { count: 0, amount: 0 };
|
||||||
const cancelledInfo = stats.by_status?.cancelled || { count: 0, amount: 0 };
|
const cancelledInfo = stats.byStatus?.cancelled || { count: 0, amount: 0 };
|
||||||
const totalOrders = paidInfo.count + pendingInfo.count + cancelledInfo.count;
|
const totalOrders = paidInfo.count + pendingInfo.count + cancelledInfo.count;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -86,14 +86,14 @@ const AdminPaymentStats: React.FC = () => {
|
|||||||
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5' }}>
|
<Card bordered={false} style={{ borderRadius: 12, border: '1px solid #f0f0f5' }}>
|
||||||
<Statistic
|
<Statistic
|
||||||
title="今日收入"
|
title="今日收入"
|
||||||
value={stats.today.paid_amount}
|
value={stats.today.paidAmount}
|
||||||
precision={2}
|
precision={2}
|
||||||
prefix={<DollarOutlined style={{ color: '#10b981' }} />}
|
prefix={<DollarOutlined style={{ color: '#10b981' }} />}
|
||||||
suffix="元"
|
suffix="元"
|
||||||
valueStyle={{ color: '#10b981', fontWeight: 700 }}
|
valueStyle={{ color: '#10b981', fontWeight: 700 }}
|
||||||
/>
|
/>
|
||||||
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
<Typography.Text type="secondary" style={{ fontSize: 12 }}>
|
||||||
{stats.today.paid_count} 笔订单
|
{stats.today.paidCount} 笔订单
|
||||||
</Typography.Text>
|
</Typography.Text>
|
||||||
</Card>
|
</Card>
|
||||||
</Col>
|
</Col>
|
||||||
@@ -147,7 +147,7 @@ const AdminPaymentStats: React.FC = () => {
|
|||||||
title={<Space><DollarOutlined />订单状态分布</Space>}>
|
title={<Space><DollarOutlined />订单状态分布</Space>}>
|
||||||
<Row gutter={16}>
|
<Row gutter={16}>
|
||||||
{['paid', 'pending', 'cancelled'].map(s => {
|
{['paid', 'pending', 'cancelled'].map(s => {
|
||||||
const info = stats.by_status?.[s] || { count: 0, amount: 0 };
|
const info = stats.byStatus?.[s] || { count: 0, amount: 0 };
|
||||||
const c = statusConfig[s];
|
const c = statusConfig[s];
|
||||||
const pct = totalOrders > 0 ? ((info.count / totalOrders) * 100).toFixed(1) : '0.0';
|
const pct = totalOrders > 0 ? ((info.count / totalOrders) * 100).toFixed(1) : '0.0';
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -118,23 +118,23 @@ export interface AdminStats {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface PaymentStats {
|
export interface PaymentStats {
|
||||||
by_status: Record<string, { count: number; amount: number }>;
|
byStatus: Record<string, { count: number; amount: number }>;
|
||||||
today: { paid_count: number; paid_amount: number };
|
today: { paidCount: number; paidAmount: number };
|
||||||
recent: PaymentOrder[];
|
recent: PaymentOrder[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface PaymentOrder {
|
export interface PaymentOrder {
|
||||||
id: string;
|
id: string;
|
||||||
order_no: string;
|
orderNo: string;
|
||||||
user_id: string;
|
userId: string;
|
||||||
user?: { username: string };
|
user?: { username: string };
|
||||||
amount: number;
|
amount: number;
|
||||||
credits: number;
|
credits: number;
|
||||||
payment_method: string;
|
paymentMethod: string;
|
||||||
status: string;
|
status: string;
|
||||||
trade_no?: string;
|
tradeNo?: string;
|
||||||
paid_at?: string;
|
paidAt?: string;
|
||||||
created_at: string;
|
createdAt: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ModelConfig {
|
export interface ModelConfig {
|
||||||
|
|||||||
Reference in New Issue
Block a user