管理后台

管理员专用的 /dashboard。用 admin 角色进入已有后台,按产品需求扩展页面,无需另写一套后台框架。

Saavo 模板内置了完整的管理员控制台,覆盖用户、支付、角色、权益、工单、通知、联盟、统计和日志等常见运营功能。

开发自己的产品时,通常不需要重新搭建后台。只需要将管理员邮箱加入配置,并使用该邮箱完成注册和验证,就可以进入 /dashboard 使用现有的管理功能。只有当现有后台无法满足业务需求时,才需要在此基础上继续添加新的管理页面、路由和 API。

已有功能

模板初始化后,以下管理功能开箱即用:

模块默认入口说明
概览/dashboard运营统计
用户/dashboard/users用户管理
订阅/dashboard/payments/subscriptions订阅快照
单次购买/dashboard/payments/purchases单次购买快照
角色/dashboard/roles查看和手动调整角色
权益/dashboard/entitlement/list查看和手动授予权益
额度事件/dashboard/entitlement/events发放与消耗审计
Reaction/dashboard/reaction/events、/dashboard/reaction/commands后台事件和命令执行
OAuth 客户端/dashboard/oauth-server授权服务器客户端
工单/dashboard/tickets处理用户工单
通知/dashboard/notifications向用户发布站内通知
联盟用户/dashboard/affiliates/users推荐用户
联盟月结/dashboard/affiliates/payouts佣金结算审核
统计/dashboard/analytics/*第一方统计,受 analytics.enabled 控制
日志/dashboard/logs/system、/alert、/audit系统、告警和审计日志

页面入口统一为 /dashboard,相关 API 则集中在 /api/dashboard/* 下,并统一通过管理员验证程序进行权限校验。

管理后台概览

先体验管理后台

修改后台之前,建议先用管理员账号走一遍现有模块。

  1. 把 config/base.ts 的 adminEmails 改成自己能收到验证邮件的地址,或先用默认的 admin@saavo.dev 在本地注册。
  2. 管理员账号同样需要完成邮箱验证,它在成为管理员之前不会跳过这一认证流程。
  3. 打开 /dashboard,确认能看到用户、支付、工单等模块。
  4. 再用一个普通账号打开同一地址,应被带回首页。

默认管理员账号的创建流程如下:

邮箱写入 adminEmails
↓
该账号注册并完成邮箱验证
↓
系统授予 admin 角色
↓
可以访问 /dashboard

非管理员访问后台页面时,会被重定向到首页或登录页。

提示

开发人员通常不需要重新实现这些后台页面,而是确认管理员入口可用,再按产品需要增加少数管理功能。

配置管理后台

默认管理后台以运营模板已有模块为目标。正式上线前,至少确认管理员是谁。

添加管理员

Saavo 通过 config/base.ts 中的 adminEmails 设置管理员:

adminEmails: ['admin@your-domain.com'],

用该邮箱注册账号并完成邮箱验证后,即可获得 admin 角色。地址必须完全匹配,不会把 admin+test@example.com 当成 admin@example.com。

adminEmails 不是绕过认证的超级账号。管理员首先是普通用户,只有已完成验证的邮箱与配置中的地址一致,才会获得管理员身份。

建议产品初始化后尽早创建自己的管理员账号,并确认能正常进入后台。

隐藏不需要的管理模块

统计功能受 config/deploy.ts 的 analytics.enabled 配置控制。关闭第一方统计后,后台不再显示统计入口。

其它管理模块目前没有单独的后台页面开关。即使产品暂时不使用工单、联盟或 OAuth 客户端等功能,对应页面仍然可能对管理员可见。如果需要彻底隐藏这些入口,可以再调整 Dashboard 的导航配置。

添加员工角色前先设计权限

当前管理后台只认可 admin 角色。对 roles.ts 的简单改动,不会让该角色进入 /dashboard,也不会自动限制它能操作的模块。

如果产品不需要权限分级,管理后台继续使用 admin,新的管理 API 也走同一套验证程序。如果确实需要员工分级,必须把它作为完整授权需求处理:定义能力、调整服务端验证程序、限制 API,并验证每个后台页面。如果只是通过前端隐藏入口来限制不同角色的访问权限,是不安全的。

扩展管理后台

配置好管理员后,产品自己的管理功能应接到现有 /dashboard。你需要根据自身的业务实现后台、前台和 API 的权限控制。

保护管理页面

独立的服务端页面对照 src/pages/dashboard.tsx:先通过权限校验,再通过管理员验证程序确认管理员身份。

const guardResult = authenticatedGuard(c);

if (!guardResult.success) {
    return c.redirect(
        getFullPath(guardResult.details?.redirectUrl as string, locale),
    );
}

if (!await authz.isAdmin(c)) {
    return c.redirect(getFullPath('/', locale));
}

完整示例见:

管理员页面

保护管理 API

管理 API 使用 requireDashboardAdmin。把它挂在 /api/dashboard 下时,所有子路由都会自动受保护:

dashboardApi.use('*', requireDashboardAdmin);

不要只在 React 组件里判断 roles.includes('admin')。客户端角色列表只能控制显示,不能作为安全边界。

添加管理页面

需要新的管理功能时,沿用现有 SPA 渲染模式:

  1. 在 src/components/client/Dashboard/pages/ 增加页面组件。
  2. 在 Dashboard/index.tsx 增加路由。
  3. 在 Dashboard/const.ts 增加导航项。
  4. 对应 API 放到 src/api/dashboard/,从而自动使用管理员验证程序。

如果只是查看或调整已有的用户、角色、权益和支付数据,优先用现成模块,不要再做一套列表页。如果确实需要新的列表页,则需要你自行实现权限控制。

上线检查

后台是高权限入口,上线前建议至少确认:

  • adminEmails 已换成自己能完成验证的地址,不再使用 admin@saavo.dev。
  • 管理员可以正常打开 /dashboard 并看到预期模块。
  • 普通用户访问 /dashboard 会被带回首页。
  • 普通用户调用 /api/dashboard/* 得到 401 或 403。
  • 新的管理 API 挂在 dashboard 路由下,或显式使用了 requireDashboardAdmin。
  • 如关闭了统计,后台统计菜单不再出现。

建议用一个全新的管理员账号和一个普通账号分别测试,不要只依赖开发期间一直存在的本地用户。

常见问题

接下来

根据接下来要开发的功能,可以继续阅读:

大多数产品走完本章后,只需要把管理员邮箱换成自己的。

真正的产品管理功能,再按现有 Dashboard 的方式往里加页面即可。