设备页面完整性检查清单

页面地址

  • 本地开发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...
  • 绑定成功提示
  • 绑定失败错误提示
  • 绑定成功后自动刷新设备列表
  • 绑定成功后清空输入框

测试步骤:

  1. 输入设备名称(可选,默认"我的小智")
  2. 输入 Token 或完整 URL
  3. 点击"绑定设备"
  4. 查看绑定结果

✅ 4. 设备列表功能

4.1 列表显示

  • 显示已绑定设备列表
  • 无设备时显示提示信息
  • 每个设备显示:
    • 设备名称(带机器人图标)
    • 设备ID
    • Agent ID
    • 启用状态(已启用/已禁用)
    • 绑定时间

4.2 操作功能

  • 刷新按钮(🔄 刷新)
  • 解绑按钮(每个设备卡片)
  • 解绑确认对话框
  • 解绑成功后自动刷新列表

测试步骤:

  1. 绑定一个设备
  2. 查看设备是否出现在列表中
  3. 点击"刷新"按钮
  4. 点击"解绑"按钮测试解绑功能

✅ 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:未登录访问

步骤:

  1. 清除 localStorage:localStorage.clear()
  2. 访问 /user/devices
  3. 应该显示"请先登录"提示

预期结果: ✅ 显示登录提示

测试用例 2:正常登录后访问

步骤:

  1. 使用 admin@mbe-test.com / Test@123456 登录
  2. 访问 /user/devices
  3. 应该自动加载设备列表

预期结果: ✅ 显示设备列表(可能为空)

测试用例 3:绑定设备

步骤:

  1. 在小智 APP 获取 Token
  2. 在设备页面输入 Token
  3. 点击"绑定设备"
  4. 查看绑定结果

预期结果: ✅ 绑定成功,设备出现在列表中

测试用例 4:解绑设备

步骤:

  1. 在设备列表中找到已绑定的设备
  2. 点击"解绑"按钮
  3. 确认解绑
  4. 查看设备是否从列表中消失

预期结果: ✅ 设备已解绑,列表更新

测试用例 5:Token 过期处理

步骤:

  1. 登录后访问设备页面
  2. 等待 token 过期(或手动修改 token)
  3. 刷新页面或执行操作

预期结果: ✅ 显示"登录已过期"提示,清除过期 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 检查状态:✅ 已通过完整性检查