353 lines
12 KiB
Markdown
353 lines
12 KiB
Markdown
|
|
# 管理后台登录与密码管理 - 功能设计
|
|||
|
|
|
|||
|
|
> **创建日期**: 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)
|