成为全栈·React 管理后台篇·统计看板:从数字堆砌到可执行的工作入口
看板的价值不是让数字显得漂亮,而是帮助使用者判断现在发生了什么,以及下一步应该去哪里处理。

前言
管理后台首页很容易变成四张大数字卡片加一张饼图。页面看起来完整,用户看完却仍要去侧栏逐个寻找待审文章和待复核评论。数字提供了信息,没有形成行动。
这个后台最终把看板当作工作入口:除了站点规模,还显示待办数量、近期内容和直接筛选链接;不同数据块独立加载和失败,不让一张图拖垮整页。
先区分规模指标与行动指标
已发布文章、已通过评论、活跃会员和累计阅读量描述站点规模。待审文章则代表当前工作量。两类数字的视觉和交互应该不同:
- 规模指标用于观察,不一定可点击;
- 行动指标必须说明含义,并进入已经筛选好的处理列表。
<StatCard
label="待审文章"
value={pending.data}
hint="点击查看需要处理的投稿"
to="/articles?status=pending"
/>
页面顶部还提供“写文章”“处理待审文章”“处理待复核评论”三个明确动作。用户不必先阅读所有图表,最常见任务可以立即开始。

查询只取完成决策所需的数据
待审卡片只需要 total,因此请求 pageSize=1,避免为了一个数字传回整页文章:
const pending = useQuery({
queryKey: ['articles', 'admin', 'pending-count'],
queryFn: () => listAdminArticles({ status: 'pending', pageSize: 1 }),
select: (page) => page.pagination.total,
})
近期文章取 5 条并按 -createdAt 排序。近期评论接口不支持 sort,页面只能取默认前 5 条后按 createdAt 兜底排序。这不能保证它们就是全库真正最新五条;文章在代码注释和本篇中都明确承认这个契约边界。
若“全站最新”对业务重要,正确做法是给接口增加排序能力,而不是拉取大量评论到浏览器再排序。
看板权限决定数据是否请求
只有具备文章管理能力的用户才查询待审数量与近期文章,具备评论审核能力才查询近期评论:
useQuery({
queryKey: ['comments', 'admin', 'recent'],
queryFn: loadRecentComments,
enabled: canComments,
})
这不仅隐藏卡片,也避免发送注定 403 的请求。前端判断仍只是体验层,后端继续验证每个接口。
当前 editor/admin 都能看到内容工作区;若未来角色能力变化,看板应复用 permission 函数,而不是再写一套 role 判断。
每块数据独立失败
站点统计、分类分布、待审数量、近期文章和近期评论来自不同查询。若分类统计失败,近期文章仍然有价值;把它们合并成一个全屏 loading 或错误页,会放大局部故障。
当前每个卡片区域都有自己的 pending、error、empty 与 success:数字使用骨架,列表使用五行骨架,图表为空显示“暂无分类数据”,错误提供局部重试。
独立错误态也帮助定位问题。公开 stats 正常而后台文章失败,往往说明认证或管理端点异常;整页只显示“加载失败”会丢掉这条诊断线索。仪表盘因此也是一枚活体探针:它同时经过代理、信封、令牌、分页和图表转换链路。
图表必须回答一个具体问题
分类环形图回答“内容主要分布在哪些分类”。如果只有颜色没有数值、图例名称被截断,图表就只剩装饰。数据为空时更不能渲染一个全灰圆环,让用户猜它代表零还是加载失败。
图表适合比较构成,近期内容列表适合查看具体变化,两者不能互相替代。阅读量趋势若只有一个累计值,也不应硬画折线;需要后端提供按日序列后,才能讨论增长或异常。
近期内容要能继续工作
近期文章标题链接到编辑页,同时显示分类、创建时间和状态标签;近期评论展示内容摘要、作者、时间与审核状态,并链接到评论处理页。看板不是内容终点,而是缩短从发现到处理的路径。
状态颜色使用与列表页相同的语义令牌。若看板把 pending 画成绿色,列表却使用橙色,同一个概念会产生两套视觉语言。共享 token 比复制 Tailwind 颜色更可靠。
数据新鲜度来自写操作失效
发布文章后,文章和 site 查询都会失效,因此已发布数量、待审数量和近期文章重新确认。审核评论同样应影响评论列表与相关统计。
看板不能依赖频繁轮询掩盖失效关系。对管理动作而言,写后主动失效最及时;对外部持续变化的数据,再按业务需要增加轮询或实时推送。
指标名称必须带清楚口径
“文章数”可能指全部记录、未删除记录或已发布文章;“评论数”可能包含拒绝和待复核。当前卡片明确写“已发布文章”“已通过评论”,避免把公开规模与后台总量混在一起。
活跃会员的“活跃”也必须由后端定义。如果接口实际只是未禁用账号数量,文案就不应暗示最近登录活跃。指标口径应该在契约或统计文档中固定,前端不能为了好听自行改名。
累计阅读量是累加指标,适合展示总规模,却不能说明近期增长。没有时间序列时,不画趋势箭头,也不拿两个不同刷新时刻的偶然差值冒充日增长。
数字格式要帮助比较
大数字可以使用千位分隔,但是否缩写成 12.3k 要看读者是否需要精确值。管理后台的待审数量通常较小且影响工作,必须显示准确整数;累计阅读量可以缩写,但最好通过 title 或辅助文本提供完整数值。
加载时使用接近最终尺寸的骨架,避免数字出现后卡片高度跳动。零是合法结果,不能用 value || '—' 把 0 当作缺失;只有 undefined 才表示尚未得到数据。
看板不是所有报表的入口
为了显得丰富,把十几张图都堆到首页会增加请求、首屏体积和理解成本。看板只保留每天需要判断的内容;历史趋势、来源分析和详细运营指标应进入独立报表页。
每增加一个组件都要回答:谁会据此采取什么动作,更新频率是多少,数据失败是否影响其它区域。如果没有清楚答案,宁可暂时不展示。留白比无目的图表更专业。
时间和排序要使用同一语义
近期文章显示 createdAt,而“最近修改”则应该按 updatedAt。标题和排序字段必须一致,否则用户刚修改旧文章,却在“近期文章”中找不到,会误解数据没有更新。
当前代码明确按 createdAt 展示新创建内容。若产品更需要继续最近编辑工作,应改成 updatedAt 并让接口支持对应排序,而不是只改卡片标题。
小结
有效看板先区分规模与待办,再用权限控制查询,用局部状态隔离故障,并把卡片和近期内容连接到具体工作页面。图表只在能够回答问题时出现,契约不支持的“最新”语义也要坦白说明。
各位看官,评价看板时可以问一句:用户看到这个数字以后能做什么?如果答案永远是“再去侧栏找找”,它还只是报表,没有成为工作入口。
延伸阅读
- 列表页范式
- 站点配置页
- TanStack Query 不只是缓存
如果这篇文章对你有帮助,欢迎订阅我的 CSDN 专栏 「成为全栈」:
🔗 专栏地址:https://blog.csdn.net/fungleo/category_13204651.html
📦 本系列配套代码仓库:https://github.com/fengcms/become-a-full-stack-developer

网硕互联帮助中心

评论前必须登录!
注册