# 执行计划：门口屏模拟器全局配置定时拉取

> **对应 PRD**: `_PRD_需求优化_门口屏全局配置定时拉取.md`
> **创建日期**: 2026-08-19
> **状态**: 待执行

---

## 阶段一：扩展 DoorTokenClient —— 新增 get_ex_global_config()

**目标**：在 `door_token_client.py` 中新增全局配置接口调用能力。

### 任务清单

| # | 任务 | 状态 |
|---|------|------|
| 1.1 | 新增 `EX_GLOBAL_CONFIG_API_PATH = "/exapi/systemConfiguration/exGlobalConfig/encrypt"` 常量 | ✅ |
| 1.2 | 新增 `get_ex_global_config(authorization, company_number)` 实例方法：GET 请求 + 动态签名头 + companyNumber 查询参数 | ✅ |
| 1.3 | 查询参数构造：`companyNumber={token响应中的 companyNumber}` | ✅ |
| 1.4 | 动态签名复用 `_generate_dynamic_sign(params, bearer_token)`（已实现） | ✅ |
| 1.5 | 响应校验：仅判断 HTTP 200 + success=true，不解析加密 result | ✅ |
| 1.6 | 错误处理：网络错误/超时不重试（下次定时再试），业务失败警告日志 | ✅ |

### 关键设计决策

1. **GET 请求 + query 参数**：与消息列表接口（GET）模式一致，与人脸页面接口（POST + form-urlencoded）不同
2. **Content-Type: application/json**：日志显示该接口 Content-Type 为 `application/json`（虽然是 GET 无 body，但保留该头与真实设备一致）
3. **查询参数 companyNumber**：直接从 token 响应 `token.companyNumber` 取值，已回填到 `topic_params.company_id`
4. **Authorization 格式**：与消息列表/人脸页面一致，使用 `BearereyJ...`（无空格格式）

---

## 阶段二：DoorSimulator 集成 —— 定时循环中追加全局配置调用

**目标**：在现有定时循环中，每次循环追加一次全局配置接口调用。

### 任务清单

| # | 任务 | 状态 |
|---|------|------|
| 2.1 | 新增 `_call_ex_global_config_once()` 方法：单次调用全局配置接口 + 记录 ReportLog | ✅ |
| 2.2 | 修改 `_message_list_loop()`：每次循环追加调用 `_call_ex_global_config_once()` | ✅ |
| 2.3 | 修改 `_start_message_list_polling()`：首次立即调用时也包含全局配置接口 | ✅ |
| 2.4 | 更新线程日志描述（消息列表/人脸页面 → 三个接口） | ✅ |

### 关键设计决策

1. **共用同一定时线程**：三个接口（消息列表、人脸页面、全局配置）在同一个循环中串行调用
2. **调用顺序**：消息列表 → 人脸页面 → 全局配置（顺序不重要，三个接口独立）
3. **失败不中断**：任一接口失败不影响其他接口的调用，也不影响下一次定时循环
4. **首次立即执行**：在 `_start_message_list_polling()` 中首次调用时，三个接口都立即执行一次

---

## 阶段三：验证

| # | 验证项 | 验证方式 | 状态 |
|---|--------|----------|------|
| 3.1 | Python 语法检查 | `python -m py_compile backend/app/simulators/door_token_client.py` | ✅ 通过 |
| 3.2 | Python 语法检查 | `python -m py_compile backend/app/simulators/door_simulator.py` | ✅ 通过 |
| 3.3 | 本地真实调用验证：token → 全局配置接口 HTTP 200 + success=true | 本地脚本调用 | ✅ 通过（code=200, success=True） |

### 验证过程记录

- **端到端验证**：通过 `DoorTokenClient.get_token()` + `get_ex_global_config()` 完整链路调用成功
- **参数确认**：只需 `companyNumber` 一个查询参数（GET 请求），与日志一致
- **Content-Type**：设为 `application/json` 与真实设备日志一致（GET 无 body，但头信息保留）

---

## 影响范围

| 文件 | 变更类型 | 说明 |
|------|----------|------|
| `backend/app/simulators/door_token_client.py` | 修改 | 新增 `get_ex_global_config()` 方法 + 常量 |
| `backend/app/simulators/door_simulator.py` | 修改 | 定时循环中追加全局配置调用 |