12 KiB
12 KiB
管理后台登录与密码管理 - 功能设计
创建日期: 2026-07-07 版本: v1.0 状态: 开发中
1. 产品定义
1.1 产品目标
| 目标 | 描述 |
|---|---|
| G1 | 企微免密登录 - 检测企微登录账号且具有管理员角色,免密直接进入 |
| G2 | 企微扫码登录 - 原有企微OAuth+OTP登录方式保持不变 |
| G3 | 账号密码+OTP登录 - 新增本地账号密码认证方式,配合OTP二次验证 |
| G4 | 超级管理员账户管理 - 超级管理员为系统本地账户,可添加/管理普通账号 |
| G5 | 修改密码 - 管理员可自行修改登录密码 |
| G6 | 管理员重置密码 - 管理员可强制重置坐席密码 |
| G7 | 忘记密码重置 - 通过企微扫码验证后重置密码 |
1.2 用户故事
| ID | 角色 | 需求描述 | 价值 |
|---|---|---|---|
| US-1 | 管理员 | 我需要使用企微免密登录管理后台 | 在企微环境中直接进入,无需输入任何凭证 |
| US-2 | 管理员 | 我需要使用企微扫码登录管理后台 | 扫码授权后进入,需OTP验证 |
| US-3 | 管理员 | 我需要使用账号密码+OTP登录管理后台 | 不依赖企微也能登录,提升可用性 |
| US-4 | 超级管理员 | 我需要在后台添加/编辑/删除普通管理员账号 | 集中管理后台用户 |
| US-5 | 超级管理员 | 首次登录时绑定OTP和企微 | 启用双因素认证增强安全性 |
| US-6 | 管理员 | 我需要修改自己的登录密码 | 定期更换密码提升账户安全 |
| US-7 | 管理员 | 我需要帮助坐席重置密码 | 坐席忘记密码时帮助恢复访问 |
| US-8 | 坐席 | 我在忘记原密码时需要通过企微验证后重置 | 忘记密码时仍能恢复访问 |
1.3 需求池
P0 - 必须实现
| ID | 需求描述 | 验收标准 |
|---|---|---|
| P0-1 | 企微免密登录API | 检测企微JS-SDK获取userid,验证具有管理员角色,免密直接返回Token |
| P0-2 | 企微扫码登录API | 复用现有企微OAuth+OTP流程 |
| P0-3 | 账号密码登录API | 支持 username/password 认证,返回Token |
| P0-4 | 密码加密存储 | 使用 bcrypt 哈希密码,不可明文存储 |
| P0-5 | OTP 验证 | 复用现有 Redis OTP 机制,支持 TOTP |
| P0-6 | 登录页面UI | 智能检测企微登录状态,显示三种登录方式入口 |
| P0-7 | 超级管理员账户 | 系统初始化时创建默认超级管理员账户 |
| P0-8 | 用户管理CRUD | 超级管理员可添加/编辑/禁用/删除普通管理员 |
| P0-9 | 首次登录绑定逻辑 | 首次成功登录时自动绑定OTP Secret和企微UserID |
| P0-10 | 坐席修改密码API | POST /api/agents/password,支持旧密码验证+新密码修改 |
| P0-11 | 坐席修改密码UI | 个人中心/设置页面提供"修改密码"入口,弹窗表单 |
| P0-12 | 管理员重置坐席密码API | POST /api/agents/password/reset,管理员强制重置 |
| P0-13 | 忘记密码-企微扫码重置 | 通过企微OAuth扫码验证后重置密码 |
P1 - 建议实现
| ID | 需求描述 | 验收标准 |
|---|---|---|
| P1-1 | 登录失败限流 | 连续5次密码错误,锁定账户15分钟 |
| P1-2 | 密码强度校验 | 密码至少8位,含大小写字母+数字 |
| P1-3 | 密码过期提醒 | 密码90天后提醒修改 |
2. 技术设计
2.1 数据库设计
-- 新增字段到 admin_user 表
ALTER TABLE admin_user ADD COLUMN password_hash VARCHAR(255);
ALTER TABLE admin_user ADD COLUMN is_super_admin BOOLEAN DEFAULT FALSE;
ALTER TABLE admin_user ADD COLUMN otp_secret VARCHAR(32);
ALTER TABLE admin_user ADD COLUMN wecom_user_id VARCHAR(64);
ALTER TABLE admin_user ADD COLUMN last_login_at TIMESTAMP;
ALTER TABLE admin_user ADD COLUMN failed_login_attempts INT DEFAULT 0;
ALTER TABLE admin_user ADD COLUMN locked_until TIMESTAMP;
-- 坐席表已有 password_hash 字段
-- agents.password_hash - bcrypt 哈希
2.2 API 端点
认证相关
| 方法 | 路径 | 认证 | 描述 |
|---|---|---|---|
| POST | /api/auth/login/password | 公开 | 账号密码+OTP登录 |
| POST | /api/auth/login/wecom | 企微 | 企微扫码登录 |
| POST | /api/auth/login/wecom-silent | 企微 | 企微免密登录 |
用户管理(仅超级管理员)
| 方法 | 路径 | 认证 | 描述 |
|---|---|---|---|
| GET | /api/auth/users | 超级管理员 | 获取用户列表 |
| POST | /api/auth/users | 超级管理员 | 创建用户 |
| PUT | /api/auth/users/{id} | 超级管理员 | 更新用户 |
| DELETE | /api/auth/users/{id} | 超级管理员 | 删除用户 |
| POST | /api/auth/users/{id}/disable | 超级管理员 | 禁用用户 |
密码管理
| 方法 | 路径 | 认证 | 描述 |
|---|---|---|---|
| POST | /api/agents/password | 登录态 | 坐席修改密码(需旧密码) |
| POST | /api/agents/password/reset | 管理员 | 管理员重置坐席密码(强制) |
| POST | /api/agents/password/reset-by-wecom | 企微 OAuth | 忘记密码重置(企微扫码) |
2.3 请求/响应 Schema
账号密码登录
// Request: POST /api/auth/login/password
{
"username": "string",
"password": "string",
"otp_code": "string" // TOTP 6位验证码
}
// Response: 200 OK
{
"code": 0,
"data": {
"token": "string",
"user": { "id": "string", "username": "string", "role": "string" }
}
}
坐席修改密码
// Request: POST /api/agents/password
{
"old_password": "string", // 旧密码(必填)
"new_password": "string" // 新密码,6-128位
}
// Response: 200 OK
{
"code": 0,
"message": "密码修改成功"
}
// Error: 400 Bad Request
{
"code": 1001,
"message": "旧密码错误"
}
管理员重置密码
// Request: POST /api/agents/password/reset
{
"user_id": "string", // 坐席 user_id
"new_password": "string" // 新密码,6-128位
}
// Response: 200 OK
{
"code": 0,
"message": "密码重置成功"
}
忘记密码重置(企微扫码)
// Step 1: 获取企微 OAuth URL
// Request: GET /api/agents/password/reset/wecom-auth-url
// Step 2: 企微扫码回调
// Request: POST /api/agents/password/reset/callback
{
"code": "string", // 企微授权 code
"new_password": "string" // 新密码
}
3. UI/UX 设计
3.1 管理后台登录页
+------------------------------------------+
| IT智能服务台 |
| 管理后台登录 |
+------------------------------------------+
| |
| [ 企微扫码登录 ] [ 账号密码登录 ] |
| |
| +------------------------------------+ |
| | 用户名: [____________] | |
| +------------------------------------+ |
| | 密码: [____________] | |
| +------------------------------------+ |
| | OTP: [______] [发送验证码] | |
| +------------------------------------+ |
| | [ 登录 ] | |
| +------------------------------------+ |
| |
| 首次登录自动绑定OTP和企业微信 |
+------------------------------------------+
3.2 管理端 - 坐席列表重置密码
入口: 坐席管理 → 列表操作列 → "重置密码" 按钮
+------------------------------------------+
| 重置密码 X |
+------------------------------------------+
| 坐席: tangzhenzhen |
| |
| 新密码: [____________] |
| 确认密码: [____________] |
| |
| [ 取消 ] [ 确认重置 ] |
+------------------------------------------+
3.3 坐席工作台 - 修改密码
入口: 右上角头像 → "修改密码"
+------------------------------------------+
| 修改密码 X |
+------------------------------------------+
| 旧密码: [____________] |
| 新密码: [____________] |
| 确认密码: [____________] |
| |
| [ 取消 ] [ 确认修改 ] |
+------------------------------------------+
3.4 坐席登录页 - 忘记密码
入口: 登录页 → "忘记密码?" 链接
+------------------------------------------+
| 忘记密码 - 通过企微验证 |
+------------------------------------------+
| |
| [ 企微二维码 ] |
| 请用企业微信扫码验证身份 |
| |
| +------------------------------------+ |
| | 新密码: [____________] | |
| +------------------------------------+ |
| | 确认密码: [____________] | |
| +------------------------------------+ |
| |
| [ 返回登录 ] [ 确认重置 ] |
+------------------------------------------+
4. 测试用例
4.1 账号密码登录
| 用例 ID | 场景 | 预期结果 |
|---|---|---|
| T01-01 | 正确账号+密码+OTP | 登录成功,返回Token |
| T01-02 | 错误密码 | 返回错误提示,密码错误 |
| T01-03 | 错误OTP | 返回错误提示,OTP验证码错误 |
| T01-04 | 账户已锁定 | 返回错误提示,账户已锁定 |
| T01-05 | 不存在账户 | 返回错误提示,用户不存在 |
4.2 坐席修改密码
| 用例 ID | 场景 | 预期结果 |
|---|---|---|
| T02-01 | 正确旧密码修改 | 密码修改成功,可用新密码登录 |
| T02-02 | 错误旧密码修改 | 返回错误提示,旧密码错误 |
| T02-03 | 新密码不符合强度 | 返回错误提示,密码强度不足 |
| T02-04 | 新密码与旧密码相同 | 返回错误提示,不能与旧密码相同 |
4.3 管理员重置密码
| 用例 ID | 场景 | 预期结果 |
|---|---|---|
| T03-01 | 管理员重置坐席密码 | 密码成功重置,坐席可用新密码登录 |
| T03-02 | 重置不存在的坐席 | 返回 404 错误 |
| T03-03 | 非管理员重置密码 | 返回 403 无权限 |
4.4 忘记密码重置
| 用例 ID | 场景 | 预期结果 |
|---|---|---|
| T04-01 | 企微扫码后重置 | 密码重置成功,可新密码登录 |
| T04-02 | 扫码超时 | 返回错误,需重新扫码 |
| T04-03 | 扫码取消 | 返回错误提示 |
5. 任务分解
5.1 后端任务
| 任务 | 描述 | 状态 |
|---|---|---|
| BE-01 | 扩展 admin_user 表结构(password_hash, is_super_admin 等) | ⬜ 待开发 |
| BE-02 | 实现 POST /api/auth/login/password(账号密码+OTP登录) | ⬜ 待开发 |
| BE-03 | 实现 GET/POST /api/auth/users(用户管理CRUD) | ⬜ 待开发 |
| BE-04 | 实现 POST /api/agents/password(坐席修改密码) | ✅ 已实现 |
| BE-05 | 实现 POST /api/agents/password/reset(管理员重置) | ✅ 已实现 |
| BE-06 | 实现忘记密码-企微扫码重置流程 | ⬜ 待开发 |
| BE-07 | 超级管理员初始化逻辑 | ⬜ 待开发 |
5.2 管理后台前端任务
| 任务 | 描述 | 状态 |
|---|---|---|
| FE-AD-01 | 登录页添加账号密码登录Tab | ⬜ 待开发 |
| FE-AD-02 | 用户管理页面(CRUD) | ⬜ 待开发 |
| FE-AD-03 | 坐席列表添加"重置密码"按钮 | ✅ 已完成 |
| FE-AD-04 | 实现重置密码弹窗组件 | ✅ 已完成 |
5.3 坐席前端任务
| 任务 | 描述 | 状态 |
|---|---|---|
| FE-AG-01 | 右上角头像菜单添加"修改密码"入口 | ✅ 已完成 |
| FE-AG-02 | 实现修改密码弹窗组件 | ✅ 已完成 |
| FE-AG-03 | 登录页添加"忘记密码"入口 | ✅ 已完成 |
6. 技术约束
- 密码存储: bcrypt 哈希
- Session/Token: 复用现有 Redis Token 机制
- 现有用户体系: 企微 OAuth 登录 + OTP(保持不变)
- 密码强度: 最少6位,最多128位
- 企微集成: 复用现有企微 OAuth 流程