# 管理后台登录与密码管理 - 功能设计 > **创建日期**: 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 数据库设计 ```sql -- 新增字段到 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 #### 账号密码登录 ```typescript // 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" } } } ``` #### 坐席修改密码 ```typescript // 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": "旧密码错误" } ``` #### 管理员重置密码 ```typescript // Request: POST /api/agents/password/reset { "user_id": "string", // 坐席 user_id "new_password": "string" // 新密码,6-128位 } // Response: 200 OK { "code": 0, "message": "密码重置成功" } ``` #### 忘记密码重置(企微扫码) ```typescript // 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 流程 --- ## 7. 相关文档 - [产品需求文档 PRD](../02-产品需求/02-产品需求文档PRD-v1.2-20260704.md) - [OTP 二次验证实现](../09-部署运维/06-OTP二次验证实现.md)