import { useMemo } from 'react' import { useQuery } from '@tanstack/react-query' import { Alert, Button, Card, Space, Tag, Typography } from 'antd' import { BarChartOutlined, ReloadOutlined, ShoppingCartOutlined, TeamOutlined, WalletOutlined, } from '@ant-design/icons' import { useNavigate } from 'react-router-dom' import { fetchAdminDistributionAnalytics } from '@/features/admin/api' import { AdminPageHeader } from '@/features/admin/components/AdminPageHeader' import { DistributionSiteSelect, useDistributionSiteSelection, } from '@/features/admin/components/DistributionSiteSelect' import { useAdminSessionStore } from '@/stores/adminSession' import { getAdminBasePath } from '@/shared/api/adminClient' import { formatMoney } from '@/shared/utils/format' function errorText(error: unknown) { const response = (error as { response?: { data?: { message?: string } } })?.response if (response?.data?.message) return response.data.message return error instanceof Error ? error.message : '请求失败,请稍后重试' } function count(value?: number | null) { return (value ?? 0).toLocaleString('zh-CN') } export function AdminDistributionDashboardPage() { const navigate = useNavigate() const permissions = useAdminSessionStore(state => state.admin?.permissions) const canView = Boolean( permissions?.includes('*') || permissions?.includes('distribution:site_view') ) const selection = useDistributionSiteSelection() const siteId = selection.siteId const analyticsQuery = useQuery({ queryKey: ['admin-distribution-analytics', siteId], queryFn: () => fetchAdminDistributionAnalytics(siteId as number), enabled: canView && Boolean(siteId), }) const data = analyticsQuery.data const trendDays = data?.trend_days ?? [] const maxProfit = useMemo( () => Math.max(1, ...trendDays.map(point => point.profit_cent)), [trendDays] ) const metrics = [ { key: 'today_received', label: '今日收号', value: count(data?.today_received_count), hint: `累计收货 ${count(data?.total_received_count)} 件`, }, { key: 'active', label: '在售商品', value: count(data?.active_listing_count), hint: '已上架且审核通过', }, { key: 'today_orders', label: '今日订单', value: count(data?.today_order_count), hint: '按订单创建时间统计', }, { key: 'today_gmv', label: '今日 GMV', value: formatMoney(data?.today_gmv_cent), hint: '按支付快照实付金额', }, { key: 'today_profit', label: '今日利润', value: formatMoney(data?.today_profit_cent), hint: '站点参与方利润', accent: true, }, { key: 'month_profit', label: '本月利润', value: formatMoney(data?.month_profit_cent), hint: '自然月累计', }, { key: 'balance', label: '可用余额', value: formatMoney(data?.available_balance_cent), hint: '可申请提现', }, { key: 'today_users', label: '今日新增', value: count(data?.today_user_count), hint: `累计注册 ${count(data?.total_user_count)} 人`, }, { key: 'order_users', label: '成交客户', value: count(data?.total_order_user_count), hint: '已产生有效订单', }, { key: 'total_users', label: '累计用户', value: count(data?.total_user_count), hint: '本站注册用户', }, ] const adminBase = getAdminBasePath() const go = (path: string) => navigate(`${adminBase}${path}`) return (
近 7 天趋势 {selection.site ? {selection.site.site_name} : null} {analyticsQuery.isFetching ? 正在刷新 : null} } extra={ } /> {!canView ? ( ) : ( )} {analyticsQuery.isError ? ( void analyticsQuery.refetch()}> 重试 } /> ) : null}
{metrics.map(metric => ( {metric.label} {metric.value} {metric.hint} ))}
近 7 天经营趋势 } extra={ 收号 / 订单 / GMV / 站点利润 } > {trendDays.length === 0 ? ( {analyticsQuery.isPending ? '加载中…' : '暂无趋势数据'} ) : (
日期 收号 订单 GMV 利润 利润趋势
{trendDays.map(point => (
{point.date.slice(5)} {count(point.received_count)} {count(point.order_count)} {formatMoney(point.gmv_cent)} {formatMoney(point.profit_cent)}
))}
)}
) }