fix: connect remaining sms pages to real backend
This commit is contained in:
@@ -1,23 +1,48 @@
|
||||
import { useEffect, useMemo, useState } from 'react';
|
||||
import { Activity } from 'lucide-react';
|
||||
import { Breadcrumb, Button, Table, Tag, type TableColumn } from '@/components/ui';
|
||||
import { adminService, type Channel } from '@/mock';
|
||||
import { adminApi, type AdminChannel } from '@/api/adminApi';
|
||||
|
||||
const columns: Array<TableColumn<Channel>> = [
|
||||
const columns: Array<TableColumn<AdminChannel>> = [
|
||||
{ key: 'id', title: '通道编号', render: (record) => record.id },
|
||||
{ key: 'name', title: '通道名称', render: (record) => record.name },
|
||||
{ key: 'region', title: '区域', render: (record) => record.region },
|
||||
{ key: 'successRate', title: '成功率', render: (record) => `${record.successRate}%` },
|
||||
{ key: 'latencyMs', title: '平均延迟', render: (record) => `${record.latencyMs} ms` },
|
||||
{ key: 'carrier', title: '运营商', render: (record) => record.carrier ?? '-' },
|
||||
{ key: 'gatewayHost', title: '网关地址', render: (record) => `${record.gatewayHost}:${record.gatewayPort}` },
|
||||
{ key: 'rateLimitPerSecond', title: '限速', render: (record) => `${record.rateLimitPerSecond} 条/秒` },
|
||||
{
|
||||
key: 'enabled',
|
||||
key: 'status',
|
||||
title: '状态',
|
||||
render: (record) => <Tag tone={record.enabled ? 'success' : 'danger'}>{record.enabled ? '运行中' : '已停用'}</Tag>,
|
||||
render: (record) => <Tag tone={record.status === 'active' ? 'success' : 'danger'}>{record.status === 'active' ? '运行中' : '已停用'}</Tag>,
|
||||
},
|
||||
];
|
||||
|
||||
export function AdminMonitorPage() {
|
||||
const channels = adminService.getChannels();
|
||||
const enabledChannels = channels.filter((item) => item.enabled).length;
|
||||
const [channels, setChannels] = useState<AdminChannel[]>([]);
|
||||
const [monitor, setMonitor] = useState<Record<string, unknown>>({});
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState('');
|
||||
|
||||
function loadData() {
|
||||
setLoading(true);
|
||||
Promise.all([adminApi.listChannels(), adminApi.listMonitor()])
|
||||
.then(([channelItems, monitorData]) => {
|
||||
setChannels(channelItems.filter((item) => item.status !== 'deleted'));
|
||||
setMonitor(monitorData);
|
||||
setError('');
|
||||
})
|
||||
.catch((reason: Error) => setError(reason.message || '监控数据加载失败'))
|
||||
.finally(() => setLoading(false));
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
loadData();
|
||||
}, []);
|
||||
|
||||
const enabledChannels = channels.filter((item) => item.status === 'active').length;
|
||||
const statusGroups = Array.isArray(monitor.byStatus) ? monitor.byStatus as Array<{ status: string; _count: { _all: number } }> : [];
|
||||
const totalMessages = useMemo(() => statusGroups.reduce((sum, item) => sum + (item._count?._all ?? 0), 0), [statusGroups]);
|
||||
const deliveredMessages = useMemo(() => statusGroups.filter((item) => item.status === 'delivered').reduce((sum, item) => sum + (item._count?._all ?? 0), 0), [statusGroups]);
|
||||
const successRate = totalMessages > 0 ? ((deliveredMessages / totalMessages) * 100).toFixed(1) : '0.0';
|
||||
|
||||
return (
|
||||
<section className="page-stack">
|
||||
@@ -25,8 +50,10 @@ export function AdminMonitorPage() {
|
||||
<div>
|
||||
<Breadcrumb items={['发送监控']} />
|
||||
</div>
|
||||
<Button icon={<Activity size={16} />} variant="ghost">实时刷新</Button>
|
||||
<Button icon={<Activity size={16} />} onClick={loadData} variant="ghost">实时刷新</Button>
|
||||
</div>
|
||||
{loading ? <p className="muted">正在加载监控数据...</p> : null}
|
||||
{error ? <p className="form-error">{error}</p> : null}
|
||||
<div className="dashboard-grid">
|
||||
<div className="surface metric-card">
|
||||
<span>运行通道</span>
|
||||
@@ -35,13 +62,13 @@ export function AdminMonitorPage() {
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>平均成功率</span>
|
||||
<strong>98.5%</strong>
|
||||
<small>近 1 小时</small>
|
||||
<strong>{successRate}%</strong>
|
||||
<small>真实消息记录</small>
|
||||
</div>
|
||||
<div className="surface metric-card">
|
||||
<span>平均延迟</span>
|
||||
<strong>167 ms</strong>
|
||||
<small>全通道加权</small>
|
||||
<span>消息总量</span>
|
||||
<strong>{totalMessages.toLocaleString('zh-CN')}</strong>
|
||||
<small>按当前查询聚合</small>
|
||||
</div>
|
||||
</div>
|
||||
<div className="surface">
|
||||
|
||||
Reference in New Issue
Block a user