Admin Module UI 设计规范
自动生成时间: 2026-02-04
模块路径: workbench/NextUI.Workbench/Pages/Admin/
布局路径: workbench/NextUI.Workbench/Layout/AdminLayout.razor
1. 模块概述
Admin 模块是 NextUI 的系统管理后台,提供用户管理、角色管理、服务器配置等功能。该模块包含一个专用布局 AdminLayout 和多个管理页面。
1.1 模块结构
| 路由 |
页面 |
功能 |
/admin |
AdminOverviewPage |
管理总览仪表板 |
/admin/users |
AdminUsersPage |
用户管理 |
/admin/roles |
AdminRolesPage |
角色管理 |
/admin/groups |
AdminGroupsPage |
分组管理 |
/admin/clients |
AdminClientsPage |
客户端管理 |
/admin/profiles |
AdminProfilesPage |
配置管理 |
/admin/sessions |
AdminSessionsPage |
会话管理 |
/admin/servers |
AdminServersPage |
服务器管理 |
2. 身份认证模式
Admin 模块根据 IdentityMode 显示不同的 UI 状态:
| IdentityMode |
认证状态 |
显示内容 |
None |
未认证 |
设置向导 + "Configure Authentication" 按钮 |
Mock |
未认证 |
Demo 模式提示 + "Demo Login" 按钮 |
Oidc |
未认证 |
登录提示 + SxLoginButton |
| 任意 |
已认证但无 admin 角色 |
权限不足提示 + 当前用户信息 |
| 任意 |
已认证且有 admin 角色 |
完整的管理界面 |
2.1 检测逻辑
// AdminLayout.razor / AdminOverviewPage.razor
private async Task DetectIdentityModeAsync()
{
var result = await SetupService.DetectEnvironmentAsync();
_identityMode = result.CurrentMode;
}
3. AdminLayout 布局
3.1 组件结构
SxAuthGuard (Roles=["admin"])
├── ChildContent (已授权)
│ └── SxAppRoot
│ └── SxAppShell
│ ├── Navigation: AdminSidebar
│ ├── BottomBar: SxIdentityUserBar
│ └── Body: RouteView
├── UnauthorizedContent (未授权)
│ ├── _detectingMode=true: 加载状态 (SxProgressRing)
│ ├── IdentityMode.None + 未登录: 设置向导入口
│ ├── IdentityMode.Mock + 未登录: Demo 登录入口
│ ├── IdentityMode.Oidc + 未登录: OIDC 登录入口
│ └── 已登录但无 admin 角色: 权限不足提示
└── SxDrawer (设置抽屉)
3.2 状态变量
| 变量 |
类型 |
说明 |
_settingsOpen |
bool |
设置抽屉是否打开 |
_wizardOpen |
bool |
设置向导是否打开 |
_detectingMode |
bool |
是否正在检测配置 |
_identityMode |
IdentityMode |
当前身份认证模式 |
3.3 注入服务
| 服务 |
用途 |
INextUILocalizer L |
国际化 |
IIdentityService IdentityService |
身份认证 |
IIdentitySetupService SetupService |
配置检测 |
ICurrentUser CurrentUser |
当前用户 |
NavigationManager NavigationManager |
导航 |
4. AdminOverviewPage 概览页
4.1 页面布局
SxAuthGuard
├── ChildContent (已授权)
│ ├── MessageBar (Mock 模式警告, 可选)
│ ├── SxIdentitySetupWizard (配置向导)
│ ├── Header Section
│ │ ├── Icon + Title
│ │ └── Admin Menu (头像 + 下拉菜单)
│ ├── Stats Section (4 张统计卡片)
│ ├── Quick Actions (SxCommandBar)
│ └── Recent Activity (暂无数据)
└── UnauthorizedContent (未授权)
└── 根据 IdentityMode 显示不同提示
4.2 统计卡片
| 卡片 |
图标 |
数据源 |
链接 |
| Active Servers |
server |
ServerRegistry.GetAllServersAsync() |
/admin/servers |
| Total Users |
users |
provider.GetUsersAsync() |
/admin/users |
| System Health |
circle-check |
固定 100% |
/admin/health |
| Active Sessions |
clock |
CurrentUser.IsAuthenticated ? 1 : 0 |
/admin/sessions |
4.3 Quick Actions
使用 SxCommandBar 组件,包含以下操作:
| 操作 |
图标 |
链接 |
| Manage Users |
users |
/admin/users |
| Manage Roles |
shield-halved |
/admin/roles |
| Manage Groups |
users-rectangle |
/admin/groups |
| Manage Clients |
window-restore |
/admin/clients |
| User Profiles |
address-card |
/admin/profiles |
| Active Sessions |
clock-rotate-left |
/admin/sessions |
| Manage Servers |
server |
/admin/servers |
4.4 状态变量
| 变量 |
类型 |
说明 |
_statsLoading |
bool |
统计数据加载中 |
_serverCount |
int |
服务器数量 |
_totalUsers |
int |
用户总数 |
_activeUsers |
int |
活跃用户数 |
_wizardOpen |
bool |
设置向导是否打开 |
_identityMode |
IdentityMode |
当前身份认证模式 |
5.1 导航结构
SxNavMenu
├── SxNavMenuGroup "管理平台" (icon: shield-halved)
│ ├── 管理总览 → /admin (icon: gauge-high)
│ ├── 用户管理 → /admin/users (icon: users)
│ ├── 角色管理 → /admin/roles (icon: user-shield)
│ ├── 分组管理 → /admin/groups (icon: users-rectangle)
│ ├── 客户端管理 → /admin/clients (icon: window-restore)
│ ├── 配置管理 → /admin/profiles (icon: sliders)
│ ├── 会话管理 → /admin/sessions (icon: clock-rotate-left)
│ └── 服务器管理 → /admin/servers (icon: server)
└── SxNavMenuGroup "身份认证" (icon: id-card)
├── 概览 → /identity (icon: home)
├── 登录按钮 → /identity/login-button
├── 用户头像 → /identity/user-avatar
├── 用户信息栏 → /identity/user-bar
├── 权限守卫 → /identity/auth-guard
├── 租户切换 → /identity/tenant-switcher
├── 共享配置 → /identity/shared-profile
├── 配置管理 → /identity/shared-profile-admin
└── 分层偏好 → /identity/preferences
5.2 展开状态
两个分组默认都展开:
private HashSet<string> _expandedIds = new() { GroupAdmin, GroupIdentity };
6. AdminUsersPage 用户管理页
6.1 页面布局
SxAuthGuard
├── ChildContent (已授权)
│ ├── Header Section (Icon + Title)
│ ├── Server Selector Card
│ │ └── SxAdminServerSelector
│ ├── User Statistics Grid (4 列)
│ │ ├── Total Users
│ │ ├── Active Users
│ │ ├── Admins
│ │ └── Disabled
│ └── User List Card
│ └── SxAdminUserListConnected
└── UnauthorizedContent
6.2 统计卡片
| 卡片 |
图标 |
计算方式 |
| Total Users |
users |
result.TotalCount |
| Active Users |
user-check |
items.Count(u => u.Enabled) |
| Admins |
shield-halved |
items.Count(u => u.Roles.Contains("admin")) |
| Disabled |
user-xmark |
items.Count(u => !u.Enabled) |
7. AdminServersPage 服务器管理页
7.1 页面布局
SxAuthGuard
├── ChildContent (已授权)
│ ├── Header Section
│ ├── Server List Card
│ │ └── SxAdminServerList
│ ├── Status Messages (SxMessageBar)
│ └── Help Section (2 列 Grid)
│ ├── Supported Providers Card
│ └── Quick Start Card
└── UnauthorizedContent
7.2 支持的 Provider
| Provider |
图标 |
说明 |
| Keycloak |
key |
Full-featured identity provider |
| SharedProfile API |
id-card |
Lightweight profile management |
| NextUI Application |
globe |
Applications implementing NextUI Standard Admin API |
7.3 事件处理
| 事件 |
处理方法 |
消息 |
| OnServerSelected |
HandleServerSelected |
Success: "Server 'X' is now the default server." |
| OnServerAdded |
HandleServerAdded |
Success: "Server 'X' has been added successfully." |
| OnServerEdited |
HandleServerEdited |
Success: "Server 'X' has been updated." |
| OnServerDeleted |
HandleServerDeleted |
Warning: "Server 'X' has been deleted." |
8. 状态转换图
8.1 认证状态流程
┌─────────────────────┐
│ 页面加载 │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ _detectingMode=true│
│ 显示 Loading │
└──────────┬──────────┘
│
DetectIdentityModeAsync()
│
▼
┌────────────────┼────────────────┐
│ │ │
▼ ▼ ▼
IdentityMode.None IdentityMode.Mock IdentityMode.Oidc
│ │ │
│ │ │
┌─────────┴─────────┐ │ ┌────────┴────────┐
│ 未登录? │ │ │ 未登录? │
├─────────┬─────────┤ │ ├────────┬────────┤
│Yes │No │ │ │Yes │No │
│ │ │ │ │ │ │
▼ ▼ │ │ ▼ ▼ │
Setup Check Role │ │ Login Check Role │
Wizard ◄─┘ │ Button ◄┘
│ │ │
│ ▼ │
│ 未登录? │
│ ┌────┴────┐ │
│ │Yes │No │
│ ▼ ▼ │
│ Demo Check │
│ Login Role │
│ │ │ │
└──────┴────┬────┴──────┘
│
▼
┌───────────────────────┐
│ Has "admin" role? │
├───────────┬───────────┤
│Yes │No │
▼ ▼ │
Admin Access │
Console Denied │
9. 公共 API
9.1 AdminLayout Parameters
无外部参数,继承 LayoutComponentBase。
9.2 注入的服务
| 服务接口 |
用途 |
IIdentitySetupService |
检测身份认证配置状态 |
IIdentityService |
执行登录/登出操作 |
ICurrentUser |
获取当前用户信息 |
INextUILocalizer |
国际化文本 |
9.3 关键方法
// AdminLayout.razor
private async Task DetectIdentityModeAsync()
private void HandleSetupComplete(IdentityConfiguration config)
private void NavigateToDemoLogin()
private void OpenSettings()
// AdminOverviewPage.razor
private async Task LoadStatsAsync()
private void NavigateToProfile()
private void NavigateToSettings()
private async Task HandleLogout()
10. 典型使用场景 (Use Cases)
10.1 UC-1: 首次访问(无配置)
- 用户访问
/admin
- 系统检测
IdentityMode = None
- 显示设置向导入口
- 用户点击 "Configure Authentication"
- 打开
SxIdentitySetupWizard
- 用户完成配置
- 页面刷新,进入正常流程
10.2 UC-2: Demo 模式登录
- 用户访问
/admin
- 系统检测
IdentityMode = Mock
- 显示 Demo 模式提示
- 用户点击 "Demo Login"
- 跳转到
/identity
- 用户选择 "Admin" 用户登录
- 返回
/admin,显示管理界面
10.3 UC-3: OIDC 登录
- 用户访问
/admin
- 系统检测
IdentityMode = Oidc
- 显示登录提示和
SxLoginButton
- 用户点击登录
- 跳转到 OIDC Provider
- 完成认证后返回
- 显示管理界面
10.4 UC-4: 权限不足
- 用户已登录但无 admin 角色
- 访问
/admin
- 显示 "Access Denied"
- 显示当前用户名和角色列表
- 若为 Mock 模式,提示切换到 Admin 用户
11. 状态不变性测试 (State Invariants)
11.1 身份模式检测
| 操作 |
不应影响 |
| 检测配置失败 |
应默认为 IdentityMode.None |
| 用户登录/登出 |
_identityMode 不应重置 |
| 组件重新渲染 |
_identityMode 保持不变 |
11.2 统计数据加载
| 操作 |
不应影响 |
| 加载统计失败 |
应显示 0,不应抛出异常 |
| 切换服务器 |
应触发重新加载统计 |
| 用户登出 |
统计数据应重置为 0 |
12. 测试检查点
12.1 必须测试 (单元测试)
12.2 边界情况
12.3 状态不变性测试
12.4 E2E 测试 (Playwright)
13. 规范合规检查
13.1 组件使用
13.2 样式
13.3 注意事项
- ⚠️
AdminOverviewPage.razor:84 使用了 <a> 原生元素包装 SxCard
- ⚠️
AdminOverviewPage.razor:52 使用了 calc() 进行间距计算
14. 已知问题 / TODO
14.1 严重问题 (P0)
国际化 Key 未翻译 ✅ 已修复 (2026-02-04)
- 问题:
Admin.Title 显示原始 key 而非翻译文本
- 修复: 添加
Admin.Title 到 en-US.json 和 zh-CN.json
- 同时添加了
Error.PageNotFound 和 Error.PageNotFoundDescription
登录状态不跨布局持久化 - 需要进一步调查
- 现象: 在 /identity 登录后导航到 /admin 时登录状态丢失
- 原因: MockIdentityService 将认证状态存储在内存中,没有持久化到 localStorage
- 影响: 用户从其他页面导航到 Admin 时需要重新登录
- 建议: 为 MockIdentityService 添加 localStorage 持久化支持
14.2 功能缺失 (P1)
- Recent Activity 暂无数据源 - 需要实现活动日志功能
- System Health 固定 100% - 需要实现真实健康检查
- Active Sessions 只显示当前用户 - 需要实现会话管理 API
14.3 代码规范 (P2)
- 统计卡片使用原生
<a> 标签 - 考虑使用 SxLink 或 NavigationManager
- AdminOverviewPage:52 使用 calc() - 应使用 Design Token
15. 变更历史
| 日期 |
变更内容 |
| 2026-02-04 |
初始版本,由 /ui-spec /admin 命令生成 |
| 2026-02-04 |
修复设置向导循环问题,添加 IdentityMode 检测逻辑 |
| 2026-02-04 |
修复 Admin.Title 国际化问题,添加缺失的翻译 key |