fix: bound formatter memory and improve operations workflows
This commit is contained in:
@@ -2,6 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
|
||||
import { BarChart3, DollarSign, FileCheck2, ShieldCheck } from 'lucide-react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { Breadcrumb, Button, Modal, MoneyText, Table, Tag, type TableColumn } from '@/components/ui';
|
||||
import './AdminHome.css';
|
||||
import { Chart } from '@/components/ui/Chart';
|
||||
import { adminApi, type DashboardResponse, type SendQualityResponse } from '@/api/adminApi';
|
||||
import { createDualAxisBarLineOption, createLineOption } from '@/theme/chartOptions';
|
||||
@@ -170,61 +171,99 @@ export function AdminHome() {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="dashboard-grid admin-metric-grid">
|
||||
<div className="surface metric-card">
|
||||
<span>今日发送总量</span>
|
||||
<strong>{formatCount(totalSend)} 条</strong>
|
||||
<small>来自真实短信记录聚合</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日消息分片数</span>
|
||||
<strong>{formatCount(dashboard?.today.segmentCount ?? 0)} 片</strong>
|
||||
<small>来自真实分片审计记录</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>总体成功率</span>
|
||||
<strong>{averageSuccessRate.toFixed(1)}%</strong>
|
||||
<small>delivered / 今日总量</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日到达率</span>
|
||||
<strong>{(dashboard?.today.arrivalRate ?? 0).toFixed(1)}%</strong>
|
||||
<small>到达分片 / 发送总分片</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日活跃签名</span>
|
||||
<strong>{activeSignatureCount}</strong>
|
||||
<small>当天有真实发送记录的签名</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日消费金额</span>
|
||||
<strong>¥{formatCurrency(todaySpend)}</strong>
|
||||
<small>来自今日消息金额聚合</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日返还金额</span>
|
||||
<strong>¥{formatCurrency(todayReturned)}</strong>
|
||||
<small>来自今日返还流水</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日计收金额</span>
|
||||
<strong>¥{formatCurrency(todayBilled)}</strong>
|
||||
<small>成功短信计费条数 × 客户价</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日利润</span>
|
||||
<strong className={todayProfit < 0 ? 'metric-card__value--danger' : undefined}>
|
||||
¥{formatCurrency(todayProfit)}
|
||||
</strong>
|
||||
<small>计收金额 - 成功分片通道成本</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>今日利润率</span>
|
||||
<strong className={(dashboard?.today.profitRate ?? 0) < 0 ? 'metric-card__value--danger' : undefined}>
|
||||
{(dashboard?.today.profitRate ?? 0).toFixed(1)}%
|
||||
</strong>
|
||||
<small>今日利润 / 今日计收金额</small>
|
||||
</div>
|
||||
<div className="home-metrics" aria-busy={!dashboard && !error}>
|
||||
{[
|
||||
{
|
||||
label: '今日发送总量',
|
||||
value: formatCount(totalSend),
|
||||
unit: '条',
|
||||
note: '业务短信',
|
||||
group: '发送',
|
||||
icon: <BarChart3 size={18} />,
|
||||
},
|
||||
{
|
||||
label: '今日消息分片数',
|
||||
value: formatCount(dashboard?.today.segmentCount ?? 0),
|
||||
unit: '片',
|
||||
note: '实际消息分片',
|
||||
group: '发送',
|
||||
},
|
||||
{
|
||||
label: '总体成功率',
|
||||
value: averageSuccessRate.toFixed(1),
|
||||
unit: '%',
|
||||
note: '送达成功 / 今日总量',
|
||||
group: '质量',
|
||||
icon: <ShieldCheck size={18} />,
|
||||
},
|
||||
{
|
||||
label: '今日到达率',
|
||||
value: (dashboard?.today.arrivalRate ?? 0).toFixed(1),
|
||||
unit: '%',
|
||||
note: '到达分片 / 发送总分片',
|
||||
group: '质量',
|
||||
},
|
||||
{
|
||||
label: '今日活跃签名',
|
||||
value: formatCount(activeSignatureCount),
|
||||
unit: '个',
|
||||
note: '今日有真实发送记录',
|
||||
group: '发送',
|
||||
},
|
||||
{
|
||||
label: '今日消费金额',
|
||||
value: formatCurrency(todaySpend),
|
||||
unit: '元',
|
||||
note: '今日消息消费',
|
||||
group: '经营',
|
||||
icon: <DollarSign size={18} />,
|
||||
},
|
||||
{
|
||||
label: '今日返还金额',
|
||||
value: formatCurrency(todayReturned),
|
||||
unit: '元',
|
||||
note: '今日返还流水',
|
||||
group: '经营',
|
||||
},
|
||||
{
|
||||
label: '今日计收金额',
|
||||
value: formatCurrency(todayBilled),
|
||||
unit: '元',
|
||||
note: '成功计费条数 × 客户价',
|
||||
group: '经营',
|
||||
},
|
||||
{
|
||||
label: '今日利润',
|
||||
value: formatCurrency(todayProfit),
|
||||
unit: '元',
|
||||
note: '计收金额 − 成功分片通道成本',
|
||||
group: '经营',
|
||||
danger: todayProfit < 0,
|
||||
},
|
||||
{
|
||||
label: '今日利润率',
|
||||
value: (dashboard?.today.profitRate ?? 0).toFixed(1),
|
||||
unit: '%',
|
||||
note: '今日利润 / 今日计收金额',
|
||||
group: '经营',
|
||||
danger: (dashboard?.today.profitRate ?? 0) < 0,
|
||||
},
|
||||
].map((metric) => (
|
||||
<article className="home-metric" key={metric.label}>
|
||||
<div className="home-metric__heading">
|
||||
<span>{metric.label}</span>
|
||||
<span className="home-metric__category">
|
||||
{metric.icon}
|
||||
{metric.group}
|
||||
</span>
|
||||
</div>
|
||||
<div className={metric.danger ? 'home-metric__number is-negative' : 'home-metric__number'}>
|
||||
<strong>{dashboard ? metric.value : '—'}</strong>
|
||||
<span>{metric.unit}</span>
|
||||
</div>
|
||||
<p>{dashboard ? metric.note : error ? '数据暂不可用' : '正在加载…'}</p>
|
||||
</article>
|
||||
))}
|
||||
</div>
|
||||
{error ? <div className="surface ui-table__empty">{error}</div> : null}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user