diff --git a/docs/progress_callback_mechanism.md b/docs/progress_callback_mechanism.md
new file mode 100644
index 0000000..278713c
--- /dev/null
+++ b/docs/progress_callback_mechanism.md
@@ -0,0 +1,401 @@
+# 进度回调机制详解
+
+## 概述
+
+`_report_progress` 是一个基于**回调函数模式**的进度报告系统,用于后台任务(数据提取)和 GUI 主线程之间的线程安全通信。
+
+---
+
+## 架构设计
+
+### 系统架构图
+
+```mermaid
+flowchart TB
+ subgraph BG["后台线程 (Background Thread)"]
+ Extractor["DiscreteMaterialPlanExtractor"]
+ Report["_report_progress()"]
+ ProgressInfo["ProgressInfo 对象"]
+ end
+
+ subgraph Boundary["线程边界 (Thread Boundary)"]
+ Callback["progress_callback()"]
+ end
+
+ subgraph FG["主线程 (Main/GUI Thread)"]
+ Calc["ProgressCalculator
计算总体百分比"]
+ Queue["queue.Queue
线程安全队列"]
+ Poll["_poll_progress_queue()
每50ms轮询"]
+ GUI["GUI 组件
progress_bar
status_label"]
+ end
+
+ Extractor -->|"调用"| Report
+ Report -->|"创建"| ProgressInfo
+ ProgressInfo -->|"触发"| Callback
+ Callback -->|"计算"| Calc
+ Calc -->|"put"| Queue
+ Queue -->|"get"| Poll
+ Poll -->|"更新"| GUI
+
+ style Callback fill:#ff9,stroke:#333,stroke-width:2px
+ style Queue fill:#9f9,stroke:#333,stroke-width:2px
+ style Boundary fill:#ddd,stroke:#333,stroke-dasharray: 5 5
+```
+
+### 组件职责
+
+| 组件 | 职责 | 位置 |
+|------|------|------|
+| `DiscreteMaterialPlanExtractor` | 执行数据提取任务 | 后台线程 |
+| `_report_progress()` | 报告进度到回调 | 后台线程 |
+| `ProgressInfo` | 进度信息数据结构 | 跨线程 |
+| `progress_callback()` | GUI 提供的回调函数 | 主线程定义,后台调用 |
+| `ProgressCalculator` | 计算总体进度百分比 | 主线程 |
+| `queue.Queue` | 线程安全的消息队列 | 主线程 |
+| `_poll_progress_queue()` | 轮询队列并更新 GUI | 主线程 |
+
+---
+
+## 数据流程
+
+### 完整时序图
+
+```mermaid
+sequenceDiagram
+ participant Bg as 后台线程
(Extractor)
+ participant Report as _report_progress()
+ participant Callback as progress_callback()
+ participant Calc as ProgressCalculator
+ participant Queue as 进度队列
+ participant Poll as _poll_progress_queue()
+ participant GUI as GUI 组件
+
+ Bg->>Report: _report_progress('download', 2, 3, '下载中')
+ Report->>Report: 创建 ProgressInfo 对象
+ Report->>Callback: progress_callback(progress_info)
+ Note over Callback: 主线程定义的函数
在后台线程中执行
+
+ Callback->>Calc: calculate_overall_percent(progress_info)
+ Note over Calc: download 阶段
stage_offset=10%
current=2, total=3
weight=65%
result = 10 + 67%×65 = 54%
+ Calc-->>Callback: 返回 54
+
+ Callback->>Queue: put((54, '下载中'))
+ Note over Queue: 线程安全队列
缓冲区
+
+ loop 每 50ms
+ Poll->>Queue: get_nowait()
+ Queue-->>Poll: (54, '下载中')
+ Poll->>GUI: progress_bar['value'] = 54
+ Poll->>GUI: status_label['text'] = '下载中'
+ Poll->>Poll: after(50ms, 继续轮询)
+ end
+```
+
+### 进度计算逻辑
+
+```mermaid
+flowchart LR
+ A[ProgressInfo
stage=download
current=2
total=3] --> B[ProgressCalculator]
+
+ subgraph Calc["计算过程"]
+ direction TB
+ B --> C["计算阶段内进度
2/3 × 100 = 67%"]
+ C --> D["查找阶段权重
download = 65%"]
+ D --> E["查找阶段偏移
offset = 10%"]
+ E --> F["总体进度
10 + 67%×65 = 54%"]
+ end
+
+ F --> G["更新进度条
54%"]
+```
+
+---
+
+## 阶段权重分配
+
+### 进度阶段划分
+
+```mermaid
+pie title 各阶段权重分布
+ "登录 (5%)" : 5
+ "查询 (5%)" : 5
+ "下载 (65%)" : 65
+ "注销 (5%)" : 5
+ "转换 (15%)" : 15
+ "完成 (5%)" : 5
+```
+
+### 阶段详情表
+
+| 阶段 | stage | 权重 | 进度范围 | 说明 |
+|------|-------|------|----------|------|
+| 登录 | `login` | 5% | 0-5% | ERP 系统登录 |
+| 查询 | `query` | 5% | 5-10% | 查询数据库获取订单号 |
+| 下载 | `download` | 65% | 10-75% | 批量下载数据(主要耗时) |
+| 注销 | `logout` | 5% | 75-80% | 退出 ERP 系统 |
+| 转换 | `convert` | 15% | 80-95% | 转换 Excel 格式并合并 |
+| 完成 | `complete` | 5% | 95-100% | 任务完成 |
+
+---
+
+## 代码实现
+
+### 1. 后台任务:报告进度
+
+```python
+# utils/离散备料计划维护数据提取.py
+
+def _report_progress(self, stage: str, current: int, total: int, message: str, **detail):
+ """
+ 报告进度
+
+ Args:
+ stage: 阶段标识 ('login', 'query', 'download', 等)
+ current: 当前进度值 (1, 2, 3...)
+ total: 总量 (3, 100...)
+ message: 显示给用户的消息
+ **detail: 额外信息 (如 batch_index=1)
+ """
+ if self.progress_callback:
+ try:
+ from gui.progress import ProgressInfo
+ progress_info = ProgressInfo(
+ stage=stage,
+ current=current,
+ total=total,
+ message=message,
+ detail=detail
+ )
+ # 调用 GUI 提供的回调函数
+ self.progress_callback(progress_info)
+ except Exception:
+ # 回调失败不影响主流程
+ pass
+```
+
+### 2. GUI:设置回调
+
+```python
+# gui/data_extraction_tab.py
+
+def _extraction_worker(self, input_file: str, output_file: str):
+ """后台工作线程"""
+
+ # 创建进度回调函数
+ def progress_callback(progress_info: ProgressInfo):
+ # 1. 计算总体进度百分比
+ overall_percent = self.progress_calculator.calculate_overall_percent(progress_info)
+ # 2. 放入队列(线程安全)
+ self._update_progress(overall_percent, progress_info.message)
+
+ # 将回调传递给提取器
+ self.extractor.extract(
+ production_id_file=input_file,
+ output_file=output_file,
+ progress_callback=progress_callback
+ )
+```
+
+### 3. 线程安全:队列通信
+
+```python
+# gui/data_extraction_tab.py
+
+def _update_progress(self, value: int, message: str):
+ """后台线程调用,放入队列"""
+ try:
+ self.progress_queue.put_nowait((value, message))
+ except:
+ pass # 队列满时忽略
+
+def _poll_progress_queue(self):
+ """主线程轮询,更新 GUI"""
+ try:
+ while True:
+ # 非阻塞获取队列中的消息
+ progress_data = self.progress_queue.get_nowait()
+ value, message = progress_data
+ # 更新 GUI 组件
+ self.progress_bar['value'] = value
+ self.status_label.config(text=message)
+ except queue.Empty:
+ pass
+ finally:
+ # 继续轮询(每 50ms 检查一次)
+ self.after(50, self._poll_progress_queue)
+```
+
+### 4. 进度计算器
+
+```python
+# gui/progress.py
+
+class ProgressCalculator:
+ # 各阶段在总进度中的占比
+ STAGE_WEIGHTS = {
+ 'login': 5, # 0-5%
+ 'query': 5, # 5-10%
+ 'download': 65, # 10-75%
+ 'logout': 5, # 75-80%
+ 'convert': 15, # 80-95%
+ 'complete': 5, # 95-100%
+ }
+
+ def calculate_overall_percent(self, progress: ProgressInfo) -> int:
+ """计算总体进度百分比"""
+ stage = progress.stage
+
+ if stage == 'complete':
+ return 100
+
+ # 计算阶段起始百分比
+ stage_offset = self._stage_offsets[stage]
+
+ # 计算阶段内的进度百分比
+ stage_percent = progress.percent # current/total * 100
+
+ # 计算该阶段的权重
+ stage_weight = self.STAGE_WEIGHTS[stage]
+
+ # 总进度 = 阶段偏移 + (阶段内进度 × 阶段权重 / 100)
+ overall = stage_offset + int(stage_percent * stage_weight / 100)
+
+ return min(overall, 100)
+```
+
+---
+
+## 设计要点
+
+### 1. 线程安全
+
+**问题**:Tkinter 不是线程安全的,后台线程不能直接操作 GUI。
+
+```mermaid
+flowchart LR
+ A[后台线程] -->|"❌ 直接调用 GUI"| B[崩溃/未定义行为]
+ A -->|"✅ 写入队列"| C[queue.Queue]
+ C -->|"主线程读取"| D[GUI 更新]
+```
+
+**解决方案**:使用 `queue.Queue` 作为缓冲区。
+
+```python
+# 后台线程:只写入队列
+self.progress_queue.put_nowait((value, message))
+
+# 主线程:从队列读取并更新 GUI
+progress_data = self.progress_queue.get_nowait()
+self.progress_bar['value'] = progress_data[0]
+```
+
+### 2. 解耦设计
+
+```mermaid
+flowchart TB
+ A[提取器] -->|"不需要知道 GUI"| B[回调接口]
+ B -->|"由 GUI 提供"| C[实现]
+ C -->|"可以替换"| D[测试回调
日志回调
GUI 回调]
+```
+
+**好处**:
+- 提取器代码不依赖 GUI
+- 易于测试(可以传入测试回调)
+- 灵活扩展(不同场景使用不同回调)
+
+### 3. 容错处理
+
+```python
+def _report_progress(self, ...):
+ if self.progress_callback:
+ try:
+ # 调用回调
+ self.progress_callback(progress_info)
+ except Exception:
+ # 回调失败不影响主流程
+ pass
+```
+
+**保证**:进度报告失败不会中断数据提取任务。
+
+### 4. 准确的进度反映
+
+**问题**:不同阶段耗时差异大(登录 3 秒,下载 60 秒)
+
+**解决方案**:为每个阶段分配不同权重。
+
+```mermaid
+gantt
+ title 数据提取各阶段耗时示例
+ dateFormat X
+ axisFormat %s
+
+ section 任务
+ 登录 :0, 3
+ 查询 :3, 5
+ 下载第1批 :5, 25
+ 下载第2批 :25, 45
+ 下载第3批 :45, 65
+ 注销 :65, 68
+ 转换 :68, 72
+```
+
+---
+
+## 使用示例
+
+### 在提取器中报告进度
+
+```python
+# 下载批次
+for batch_index, order_ids_batch in enumerate(self.group_order_ids(order_ids, self.batch_size)):
+ # 报告批次开始
+ self._report_progress(
+ 'download',
+ batch_index,
+ total_batches,
+ f'正在下载第 {batch_index + 1}/{total_batches} 批',
+ batch_index=batch_index + 1
+ )
+
+ # 执行下载
+ downloaded_file = self.download_batch(...)
+
+ # 报告批次完成
+ self._report_progress(
+ 'download',
+ batch_index + 1,
+ total_batches,
+ f'第 {batch_index + 1} 批下载完成'
+ )
+```
+
+### 在 GUI 中接收进度
+
+```python
+from gui.progress import ProgressInfo, ProgressCalculator
+
+class DataExtractionTab(ttk.Frame):
+ def __init__(self, ...):
+ self.progress_calculator = ProgressCalculator()
+ self.progress_queue = queue.Queue()
+ self._poll_progress_queue()
+
+ def progress_callback(self, progress_info: ProgressInfo):
+ """后台任务调用的回调函数"""
+ overall_percent = self.progress_calculator.calculate_overall_percent(progress_info)
+ self._update_progress(overall_percent, progress_info.message)
+```
+
+---
+
+## 总结
+
+`_report_progress` 机制实现了:
+
+1. **线程安全**:通过队列跨线程通信
+2. **解耦设计**:提取器与 GUI 分离
+3. **准确反映**:权重分配适配实际耗时
+4. **容错能力**:回调失败不影响主流程
+5. **易于测试**:可注入测试回调
+
+这种模式适用于任何需要长时间运行任务并实时报告进度的场景。