Files
wecom_it_smart_desk/docs/04-功能设计/密码管理功能设计.md
T

353 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 管理后台登录与密码管理 - 功能设计
> **创建日期**: 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)