fix: restore daily operations quality metrics
This commit is contained in:
@@ -1,25 +1,26 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { BarChart3 } from 'lucide-react';
|
||||
import { adminApi, type DashboardResponse } from '@/api/adminApi';
|
||||
import { Breadcrumb, Button, Chart, Tag } from '@/components/ui';
|
||||
import { Breadcrumb, Button, Chart, Input, Tag } from '@/components/ui';
|
||||
import { createBarOption, createPieOption } from '@/theme/chartOptions';
|
||||
|
||||
export function AdminAnalyticsPage() {
|
||||
const [statisticsDate, setStatisticsDate] = useState(() => shanghaiDateKey());
|
||||
const [dashboard, setDashboard] = useState<DashboardResponse | null>(null);
|
||||
const [tenantStats, setTenantStats] = useState<Array<{ tenantId: string | null; _count: { _all: number }; _sum: { amountCents?: number | null } }>>([]);
|
||||
const [channelStats, setChannelStats] = useState<Array<{ channelId: string | null; _count: { _all: number }; _sum: { amountCents?: number | null } }>>([]);
|
||||
const [channelStats, setChannelStats] = useState<Array<{ channelId: string; channelName: string; total: number }>>([]);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
function loadData() {
|
||||
Promise.all([
|
||||
adminApi.getDashboard(),
|
||||
adminApi.listStatistics({ groupBy: 'tenantId' }),
|
||||
adminApi.listStatistics({ groupBy: 'channelId' }),
|
||||
adminApi.getSendQuality(statisticsDate),
|
||||
])
|
||||
.then(([dashboardData, tenantData, channelData]) => {
|
||||
.then(([dashboardData, tenantData, qualityData]) => {
|
||||
setDashboard(dashboardData);
|
||||
setTenantStats((Array.isArray(tenantData) ? tenantData : []) as Array<{ tenantId: string | null; _count: { _all: number }; _sum: { amountCents?: number | null } }>);
|
||||
setChannelStats((Array.isArray(channelData) ? channelData : []) as Array<{ channelId: string | null; _count: { _all: number }; _sum: { amountCents?: number | null } }>);
|
||||
setChannelStats(qualityData.channels.map((item) => ({ channelId: item.channelId, channelName: item.channelName, total: item.total })));
|
||||
setError('');
|
||||
})
|
||||
.catch((failure: Error) => setError(failure.message || '统计数据加载失败'));
|
||||
@@ -35,7 +36,7 @@ export function AdminAnalyticsPage() {
|
||||
}), [tenantStats]);
|
||||
|
||||
const channelOption = useMemo(() => createPieOption({
|
||||
data: channelStats.map((item) => ({ name: item.channelId ?? '未分配通道', value: item._count._all })),
|
||||
data: channelStats.map((item) => ({ name: item.channelName || item.channelId, value: item.total })),
|
||||
}), [channelStats]);
|
||||
|
||||
return (
|
||||
@@ -44,7 +45,16 @@ export function AdminAnalyticsPage() {
|
||||
<div>
|
||||
<Breadcrumb items={['数据统计']} />
|
||||
</div>
|
||||
<Button icon={<BarChart3 size={16} />} onClick={loadData} variant="ghost">刷新统计</Button>
|
||||
<div className="page-actions">
|
||||
<Input
|
||||
aria-label="通道占比统计日期"
|
||||
max={shanghaiDateKey()}
|
||||
onChange={(event) => setStatisticsDate(event.target.value)}
|
||||
type="date"
|
||||
value={statisticsDate}
|
||||
/>
|
||||
<Button icon={<BarChart3 size={16} />} onClick={loadData} variant="ghost">查询统计</Button>
|
||||
</div>
|
||||
</div>
|
||||
{error ? <p className="form-error">{error}</p> : null}
|
||||
|
||||
@@ -81,7 +91,7 @@ export function AdminAnalyticsPage() {
|
||||
<div className="section-heading">
|
||||
<div>
|
||||
<h2>通道占比</h2>
|
||||
<p className="muted">按通道消息记录聚合。</p>
|
||||
<p className="muted">{statisticsDate} 当天按真实通道提交及回执聚合。</p>
|
||||
</div>
|
||||
<Tag tone="accent">通道</Tag>
|
||||
</div>
|
||||
@@ -91,3 +101,14 @@ export function AdminAnalyticsPage() {
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
function shanghaiDateKey(value = new Date()) {
|
||||
const parts = new Intl.DateTimeFormat('en-CA', {
|
||||
timeZone: 'Asia/Shanghai',
|
||||
year: 'numeric',
|
||||
month: '2-digit',
|
||||
day: '2-digit',
|
||||
}).formatToParts(value);
|
||||
const byType = new Map(parts.map((part) => [part.type, part.value]));
|
||||
return `${byType.get('year')}-${byType.get('month')}-${byType.get('day')}`;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user