feat: 优化签名热力图与金额展示
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Download, Search } from 'lucide-react';
|
||||
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 { Breadcrumb, Button, DateRangeInput, MoneyText, Pagination, Select, Tag, type DateRangeValue } from '@/components/ui';
|
||||
import { formatCents } from '@/utils/currency';
|
||||
import { formatDateTime } from '@/utils/dateTime';
|
||||
|
||||
@@ -78,19 +78,19 @@ export function AdminProfitReportsPage() {
|
||||
<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>
|
||||
['收入合计', `¥${formatCents(summary.revenueCents)}`], ['成本合计', `¥${formatCents(summary.costCents)}`], ['利润合计', `¥${formatCents(summary.profitCents)}`], ['综合利润率', `${(summary.profitRateBps / 100).toFixed(2)}%`],
|
||||
].map(([label, value]) => <div key={label}><span>{label}</span><strong>{label.includes('合计') && ['收入合计', '成本合计', '利润合计'].includes(label) ? <MoneyText>{value}</MoneyText> : value}</strong></div>)}</div>
|
||||
</div>
|
||||
|
||||
<div className="surface">
|
||||
<div className="ui-table-wrap">
|
||||
<table className="ui-table">
|
||||
<thead><tr><th>发送日期</th><th>{dimensionType === 'application' ? '企业 / 企业应用' : '通道'}</th><th>提交</th><th>发送</th><th>未知</th><th>成功</th><th>失败</th><th>净消费</th><th>返还</th><th>成本</th><th>利润</th><th>利润率</th><th>生成时间</th></tr></thead>
|
||||
<thead><tr><th>发送日期</th><th>{dimensionType === 'application' ? '企业 / 企业应用' : '通道'}</th><th>提交</th><th>发送</th><th>未知</th><th>成功</th><th>失败</th><th>收入</th><th>成本</th><th>利润</th><th>利润率</th><th>生成时间</th></tr></thead>
|
||||
<tbody>
|
||||
{error ? <tr><td className="ui-table__empty" colSpan={13}>{error}</td></tr>
|
||||
: loading ? <tr><td className="ui-table__empty" colSpan={13}>正在加载真实利润数据...</td></tr>
|
||||
: rows.length === 0 ? <tr><td className="ui-table__empty" colSpan={13}>暂无已生成的利润报表</td></tr>
|
||||
: rows.map((row) => <tr key={row.id}><td>{row.reportDate.slice(0, 10)}</td><td><strong>{row.dimensionName}</strong>{row.tenantName ? <div className="muted">{row.tenantName}</div> : null}</td><td>{row.submittedUnits.toLocaleString('zh-CN')}</td><td>{row.sentUnits.toLocaleString('zh-CN')}</td><td>{row.unknownUnits.toLocaleString('zh-CN')}</td><td>{row.successUnits.toLocaleString('zh-CN')}</td><td>{row.failedUnits.toLocaleString('zh-CN')}</td><td>¥{formatCents(row.revenueCents)}</td><td>¥{formatCents(row.refundCents)}</td><td>¥{formatCents(row.costCents)}</td><td style={{ color: row.profitCents < 0 ? 'var(--danger)' : undefined }}>¥{formatCents(row.profitCents)}</td><td>{(row.profitRateBps / 100).toFixed(2)}%</td><td>{formatDateTime(row.generatedAt)}</td></tr>)}
|
||||
{error ? <tr><td className="ui-table__empty" colSpan={12}>{error}</td></tr>
|
||||
: loading ? <tr><td className="ui-table__empty" colSpan={12}>正在加载真实利润数据...</td></tr>
|
||||
: rows.length === 0 ? <tr><td className="ui-table__empty" colSpan={12}>暂无已生成的利润报表</td></tr>
|
||||
: rows.map((row) => <tr key={row.id}><td>{row.reportDate.slice(0, 10)}</td><td><strong>{row.dimensionName}</strong>{row.tenantName ? <div className="muted">{row.tenantName}</div> : null}</td><td>{row.submittedUnits.toLocaleString('zh-CN')}</td><td>{row.sentUnits.toLocaleString('zh-CN')}</td><td>{row.unknownUnits.toLocaleString('zh-CN')}</td><td>{row.successUnits.toLocaleString('zh-CN')}</td><td>{row.failedUnits.toLocaleString('zh-CN')}</td><td><MoneyText>¥{formatCents(row.revenueCents)}</MoneyText></td><td><MoneyText>¥{formatCents(row.costCents)}</MoneyText></td><td style={{ color: row.profitCents < 0 ? 'var(--danger)' : undefined }}><MoneyText>¥{formatCents(row.profitCents)}</MoneyText></td><td>{(row.profitRateBps / 100).toFixed(2)}%</td><td>{formatDateTime(row.generatedAt)}</td></tr>)}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
@@ -100,7 +100,7 @@ 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 };
|
||||
const emptyProfitSummary: ProfitReportSummary = { submittedUnits: 0, sentUnits: 0, unknownUnits: 0, successUnits: 0, failedUnits: 0, revenueCents: 0, costCents: 0, profitCents: 0, profitRateBps: 0 };
|
||||
|
||||
function defaultDateRange(): DateRangeValue {
|
||||
const end = new Date();
|
||||
|
||||
Reference in New Issue
Block a user