## Context

设备批量分配、批量订购和导出都属于可能耗时的异步操作，但现有页面和任务模型不统一。产品要求以相同的状态语义、进度结构、轮询节奏和恢复行为覆盖这些入口，同时不改变已有业务接口中未涉及的字段。

## Goals / Non-Goals

- Goals: 统一三类页面的公共状态展示、任务进度展示、任务恢复、轮询和错误重试行为。
- Goals: 为导出任务补齐稳定的任务标识、计数、错误摘要和更新时间字段。
- Non-Goals: 不在前端实现任务调度、任务执行、失败明细生成或后端状态流转。
- Non-Goals: 不新增“部分成功”状态，不替换既有业务接口路径，不删除导出接口原字段。

## Decisions

- Decision: 使用固定五态映射：`1=待处理`、`2=处理中`、`3=已完成`、`4=已失败`、`5=已取消`。
- Rationale: 三类任务使用同一状态语义；部分成功由计数表达，避免增加状态分支。

- Decision: 将任务轮询实现为可复用的 composable 或等价公共模块，由页面提供任务详情查询函数和终态判断函数。
- Rationale: 轮询节奏、页面可见性处理和清理逻辑必须只维护一份，避免各页面出现漂移。

- Decision: 任务恢复使用持久化的业务入口标识与 `task_id`，恢复时优先查询任务详情；任务进入终态后清理当前入口的活动任务引用。
- Rationale: 页面刷新后可以继续展示原任务，同时终态任务不会阻止用户创建新的任务。

- Decision: 轮询采用单次调度而非固定高频定时器，延迟序列为 2 秒、3 秒、5 秒，随后保持 10 秒；页面隐藏时取消待执行调度，重新可见时立即查询一次。
- Rationale: 降低无效请求，并满足页面恢复后的即时反馈要求。

- Decision: 任务失败优先使用后端安全字段 `error_summary` 作为用户文案；`error_code` 只用于前端分类和日志，不直接展示底层技术错误。
- Rationale: 保证用户可理解，同时避免泄露内部错误信息。

## Data Model

- `task_id`: 稳定任务标识，用于持久化和恢复查询。
- `status`: 五态任务状态。
- `total_count`: 任务总数。
- `success_count`: 成功数。
- `failed_count`: 失败数。
- `failure_details`: 失败明细；具体字段由业务任务详情接口定义。
- `error_code`: 稳定错误分类码。
- `error_summary`: 可安全展示的中文错误摘要。
- `updated_at`: 任务最近更新时间。

## Risks / Trade-offs

- Risk: 不同业务详情接口的失败明细字段不完全一致。
- Mitigation: 公共交互层只约束失败明细可展示，业务页面负责将各自接口字段映射为统一展示模型。

- Risk: 页面刷新时本地保存的任务已被删除或无权限访问。
- Mitigation: 清理失效任务引用，并按 403 或普通接口失败规则展示对应状态，不重新创建任务。

- Risk: 页面不可见期间任务已进入终态。
- Mitigation: 页面恢复可见后立即执行一次详情查询，并根据返回状态停止轮询。

## Migration Plan

1. 明确三类任务接口的 `task_id` 创建响应和详情查询契约。
2. 实现公共任务状态、进度模型和轮询/恢复逻辑。
3. 先接入设备批量分配、批量订购和导出页面，保留各业务原有提交参数。
4. 更新导出任务列表和详情类型，兼容旧字段并优先使用新增统一字段。
5. 验证状态、重试、权限、页面刷新、页面可见性和部分成功场景。

## Open Questions

- 批量分配和批量订购的任务详情接口路径及失败明细字段，需要以后端实际契约为准补入实施任务。
- `task_id` 的存储范围需要按业务入口区分，还是由统一任务中心集中管理，需要实施前确认。
