import { useEffect, useMemo, useState } from 'react'; import { BadgeCheck, ClipboardList, FileText, PenLine, Plus, ReceiptText, Send, WalletCards, } from 'lucide-react'; import { useNavigate } from 'react-router-dom'; import { Button, Table, Tag, type TableColumn } from '@/components/ui'; import { Chart } from '@/components/ui/Chart'; import { clientApi, type DashboardResponse } from '@/api/adminApi'; import { createLineOption, createPieOption } from '@/theme/chartOptions'; import { formatDateTime } from '@/utils/dateTime'; import { formatAmount, formatCents, moneyUnitsToYuan } from '@/utils/currency'; type RecentTaskRow = { id: string; taskNo: string; scene: string; count: number; createdAt: string; status: string; }; const columns: Array> = [ { key: 'taskNo', title: '发送批次号', render: (record) => record.taskNo }, { key: 'scene', title: '发送场景', render: (record) => record.scene }, { key: 'count', title: '发送量', render: (record) => `${record.count.toLocaleString('zh-CN')} 条` }, { key: 'createdAt', title: '创建时间', render: (record) => record.createdAt }, { key: 'status', title: '状态', render: (record) => {record.status} }, ]; export function ClientHome() { const navigate = useNavigate(); const [dashboard, setDashboard] = useState(null); const [error, setError] = useState(''); useEffect(() => { clientApi.getDashboard() .then(setDashboard) .catch((err) => { setError(err instanceof Error ? err.message : '客户端工作台加载失败'); setDashboard(null); }); }, []); const account = dashboard?.accounts[0]; const availableBalance = moneyUnitsToYuan((account?.balanceCents ?? 0) + (account?.creditCents ?? 0)); const todayRefundCents = Math.max(0, dashboard?.today.returnedCents ?? 0); const recentMessages = useMemo(() => (dashboard?.recentTasks ?? []).map((task) => ({ id: String(task.id ?? task.taskNo), taskNo: String(task.taskNo ?? task.id), scene: String(task.category ?? task.content ?? '短信发送'), count: Number(task.phoneTotal ?? task.progressTotal ?? 0), createdAt: formatDateTime(task.createdAt ? String(task.createdAt) : null), status: String(task.status ?? 'unknown'), })), [dashboard]); const latestRecharge = dashboard?.recentRecharges[0]; const sendTrendOption = useMemo( () => createLineOption({ labels: dashboard?.hourlySendTrend.map((item) => item.label) ?? [], series: [ { name: '提交量', data: dashboard?.hourlySendTrend.map((item) => item.submittedCount) ?? [] }, { name: '成功量', data: dashboard?.hourlySendTrend.map((item) => item.successCount) ?? [] }, ], }), [dashboard], ); const channelShareOption = useMemo(() => createPieOption({ data: (dashboard?.gatewayConnections ?? []).map((item) => ({ name: item.status, value: item._sum.currentConnections ?? item._count._all, })), }), [dashboard]); return (

客户端概览

短信服务工作台

查看账户余额、审核进度、发送趋势和常用业务入口。

可用发送额度 ¥{formatAmount(availableBalance)} 现金余额 ¥{formatCents(account?.balanceCents)}
今日发送 {(dashboard?.today.sent ?? 0).toLocaleString('zh-CN')} 成功率 {dashboard?.today.successRate ?? 0}%
今日消费金额 ¥{formatCents(dashboard?.today.spendCents)} 企业今日实际消费
今日返还金额 ¥{formatCents(todayRefundCents)} 异常回执与退费返还
{error ?
{error}
: null}

快捷操作

覆盖概览页常用入口。

账户状态

企业认证与资源用量。

{dashboard?.clientOverview?.certificationStatus === 'certified' ? '已认证' : '未认证'}
企业主体 {dashboard?.clientOverview?.enterpriseName ?? account?.tenant?.name ?? '企业信息未完善'}
签名数量 {dashboard?.clientOverview?.signatureCount ?? 0} 个
最近充值 {latestRecharge ? `¥${formatCents(latestRecharge.amountCents)}` : '暂无充值'}

今日发送趋势

按北京时间逐小时展示提交量和成功量。

运营商占比

按今日提交量估算。

最近发送批次

跟踪发送状态、通道和创建时间。

); }