feat: improve operations diagnostics and channel management
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Download, Search } from 'lucide-react';
|
||||
import { adminApi, type AdminChannel, type DailyProfitReport, type EnterpriseApplication, type TenantOption } from '@/api/adminApi';
|
||||
import { adminApi, type AdminChannel, type DailyProfitReport, type EnterpriseApplication, type ProfitReportSummary, type TenantOption } from '@/api/adminApi';
|
||||
import { Breadcrumb, Button, DateRangeInput, Pagination, Select, Tag, type DateRangeValue } from '@/components/ui';
|
||||
import { formatCents } from '@/utils/currency';
|
||||
import { formatDateTime } from '@/utils/dateTime';
|
||||
@@ -19,6 +19,7 @@ export function AdminProfitReportsPage() {
|
||||
const [channelId, setChannelId] = useState('');
|
||||
const [page, setPage] = useState(1);
|
||||
const [total, setTotal] = useState(0);
|
||||
const [summary, setSummary] = useState<ProfitReportSummary>(emptyProfitSummary);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
const [exporting, setExporting] = useState(false);
|
||||
@@ -37,9 +38,11 @@ export function AdminProfitReportsPage() {
|
||||
const response = await adminApi.listProfitReports({ dateFrom: dateRange.start, dateTo: dateRange.end, dimensionType, tenantId: tenantId || undefined, applicationId: applicationId || undefined, channelId: channelId || undefined, page, pageSize });
|
||||
setRows(response.items);
|
||||
setTotal(response.total);
|
||||
setSummary(response.summary);
|
||||
} catch (failure) {
|
||||
setRows([]);
|
||||
setTotal(0);
|
||||
setSummary(emptyProfitSummary);
|
||||
setError(failure instanceof Error ? failure.message : '利润报表加载失败');
|
||||
} finally {
|
||||
setLoading(false);
|
||||
@@ -71,6 +74,14 @@ export function AdminProfitReportsPage() {
|
||||
<Button icon={<Search size={16} />} onClick={() => void loadData()}>查询</Button>
|
||||
</div>
|
||||
|
||||
<div className="surface admin-report-summary">
|
||||
<div className="admin-report-summary__heading"><strong>筛选结果汇总</strong><span>统计全部匹配数据,不受当前分页影响</span></div>
|
||||
<div className="admin-report-summary__grid">{[
|
||||
['提交合计', summary.submittedUnits.toLocaleString('zh-CN')], ['发送合计', summary.sentUnits.toLocaleString('zh-CN')], ['未知合计', summary.unknownUnits.toLocaleString('zh-CN')], ['成功合计', summary.successUnits.toLocaleString('zh-CN')], ['失败合计', summary.failedUnits.toLocaleString('zh-CN')],
|
||||
['净消费合计', `¥${formatCents(summary.revenueCents)}`], ['返还合计', `¥${formatCents(summary.refundCents)}`], ['成本合计', `¥${formatCents(summary.costCents)}`], ['利润合计', `¥${formatCents(summary.profitCents)}`], ['综合利润率', `${(summary.profitRateBps / 100).toFixed(2)}%`],
|
||||
].map(([label, value]) => <div key={label}><span>{label}</span><strong>{value}</strong></div>)}</div>
|
||||
</div>
|
||||
|
||||
<div className="surface">
|
||||
<div className="ui-table-wrap">
|
||||
<table className="ui-table">
|
||||
@@ -89,6 +100,8 @@ export function AdminProfitReportsPage() {
|
||||
);
|
||||
}
|
||||
|
||||
const emptyProfitSummary: ProfitReportSummary = { submittedUnits: 0, sentUnits: 0, unknownUnits: 0, successUnits: 0, failedUnits: 0, revenueCents: 0, refundCents: 0, costCents: 0, profitCents: 0, profitRateBps: 0 };
|
||||
|
||||
function defaultDateRange(): DateRangeValue {
|
||||
const end = new Date();
|
||||
end.setDate(end.getDate() - 1);
|
||||
|
||||
Reference in New Issue
Block a user