设备页面完整性检查清单
页面地址
- 本地开发:
http://localhost:8000/user/devices - 生产环境:
https://mbe.hi-maker.com/user/devices
功能检查清单
✅ 1. 页面加载
- 页面能正常访问
- 导航栏显示正确
- 页面标题显示 "MY DEVICES"
- 页面样式正常(深色主题)
✅ 2. 认证检查
- 未登录时显示"请先登录"提示
- 已登录时自动加载设备列表
- Token 过期时显示"登录已过期"提示
- 401 错误时自动清除过期 token
测试方法:
// 在浏览器控制台检查
console.log('Token:', localStorage.getItem('token'));
console.log('User ID:', localStorage.getItem('user_id'));
console.log('User Role:', localStorage.getItem('user_role'));
✅ 3. 绑定设备功能
3.1 表单元素
- 设备名称输入框(默认值:我的小智)
- Token/接入地址输入框(支持多行)
- "绑定设备"按钮
- 绑定结果显示区域
3.2 使用说明
- 显示"如何获取 Token"的5步说明
- 说明清晰易懂
3.3 绑定流程
- 输入验证(Token 必填)
- 支持完整 URL 格式:
wss://api.xiaozhi.me/mcp/?token=eyJ... - 支持纯 Token 格式:
eyJ... - 绑定成功提示
- 绑定失败错误提示
- 绑定成功后自动刷新设备列表
- 绑定成功后清空输入框
测试步骤:
- 输入设备名称(可选,默认"我的小智")
- 输入 Token 或完整 URL
- 点击"绑定设备"
- 查看绑定结果
✅ 4. 设备列表功能
4.1 列表显示
- 显示已绑定设备列表
- 无设备时显示提示信息
- 每个设备显示:
- 设备名称(带机器人图标)
- 设备ID
- Agent ID
- 启用状态(已启用/已禁用)
- 绑定时间
4.2 操作功能
- 刷新按钮(🔄 刷新)
- 解绑按钮(每个设备卡片)
- 解绑确认对话框
- 解绑成功后自动刷新列表
测试步骤:
- 绑定一个设备
- 查看设备是否出现在列表中
- 点击"刷新"按钮
- 点击"解绑"按钮测试解绑功能
✅ 5. 错误处理
- 401 认证错误处理
- 网络错误处理
- 服务器错误处理(非 200 状态码)
- 友好的错误提示信息
✅ 6. 用户体验
- 加载状态提示("加载中...")
- 空状态提示("暂无绑定的设备")
- 成功提示(绑定成功)
- 错误提示(绑定失败)
- 操作反馈(解绑确认)
代码改进(已实施)
改进 1:Token 获取方式
之前:
const authToken = localStorage.getItem('token'); // 只在页面加载时获取一次
现在:
function getAuthToken() {
return localStorage.getItem('token'); // 每次调用时重新获取
}
优势: 确保获取最新的 token,避免 token 更新后仍使用旧值。
改进 2:统一错误处理
新增:
function handleAuthError(container) {
// 清除过期的token
localStorage.removeItem('token');
localStorage.removeItem('user_id');
localStorage.removeItem('user_role');
// 显示错误提示
container.innerHTML = `...`;
}
优势: 统一处理 401 错误,避免代码重复。
改进 3:更完善的错误检查
之前:
const data = await resp.json();
if (data.success) { ... }
现在:
if (resp.status === 401) {
handleAuthError(container);
return;
}
if (!resp.ok) {
// 处理其他错误
return;
}
const data = await resp.json();
优势: 先检查 HTTP 状态码,再解析 JSON,避免解析错误。
测试用例
测试用例 1:未登录访问
步骤:
- 清除 localStorage:
localStorage.clear() - 访问
/user/devices - 应该显示"请先登录"提示
预期结果: ✅ 显示登录提示
测试用例 2:正常登录后访问
步骤:
- 使用
admin@mbe-test.com/Test@123456登录 - 访问
/user/devices - 应该自动加载设备列表
预期结果: ✅ 显示设备列表(可能为空)
测试用例 3:绑定设备
步骤:
- 在小智 APP 获取 Token
- 在设备页面输入 Token
- 点击"绑定设备"
- 查看绑定结果
预期结果: ✅ 绑定成功,设备出现在列表中
测试用例 4:解绑设备
步骤:
- 在设备列表中找到已绑定的设备
- 点击"解绑"按钮
- 确认解绑
- 查看设备是否从列表中消失
预期结果: ✅ 设备已解绑,列表更新
测试用例 5:Token 过期处理
步骤:
- 登录后访问设备页面
- 等待 token 过期(或手动修改 token)
- 刷新页面或执行操作
预期结果: ✅ 显示"登录已过期"提示,清除过期 token
已知问题
问题 1:401 错误(已修复)
原因: Token 获取时机问题
解决方案:
- 改为每次调用时重新获取 token
- 添加统一的 401 错误处理
问题 2:绑定后需要手动刷新
状态: ✅ 已修复
解决方案: 绑定成功后自动调用 loadDevices()
接口文档
GET /api/v1/users/xiaozhi/devices
认证: 需要 Bearer Token
响应:
{
"devices": [
{
"id": "user_abc123",
"name": "我的小智",
"agent_id": "agent_123",
"enabled": true,
"created_at": "2026-01-26T10:00:00"
}
]
}
POST /api/v1/users/xiaozhi/bind
认证: 需要 Bearer Token
请求体:
{
"token_or_url": "wss://api.xiaozhi.me/mcp/?token=eyJ...",
"device_name": "我的小智"
}
响应:
{
"success": true,
"message": "小智设备 '我的小智' 绑定成功!",
"device": {
"id": "user_abc123",
"name": "我的小智",
"agent_id": "agent_123"
},
"hint": "请重启MCP客户端服务以生效"
}
DELETE /api/v1/users/xiaozhi/devices/{device_id}
认证: 需要 Bearer Token
响应:
{
"success": true,
"message": "设备已解绑"
}
调试工具
在浏览器控制台测试
// 1. 检查认证状态
console.log({
token: localStorage.getItem('token'),
user_id: localStorage.getItem('user_id'),
user_role: localStorage.getItem('user_role')
});
// 2. 手动加载设备列表
loadDevices();
// 3. 测试绑定接口
fetch('/api/v1/users/xiaozhi/bind', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + localStorage.getItem('token')
},
body: JSON.stringify({
token_or_url: 'wss://api.xiaozhi.me/mcp/?token=your-token',
device_name: '测试设备'
})
})
.then(res => res.json())
.then(data => console.log(data));
相关文件
- 页面代码:
src/api/ui.py-user_devices_page()函数 - API 接口:
src/users/router.py-/xiaozhi/devices相关接口 - 故障排除:
docs/TROUBLESHOOTING_401.md
最后更新:2026-01-26 检查状态:✅ 已通过完整性检查