## ADDED Requirements

### Requirement: Unified Async Task States

The admin frontend SHALL use one state vocabulary for device batch allocation, batch ordering, and export tasks: `1=待处理`, `2=处理中`, `3=已完成`, `4=已失败`, and `5=已取消`.

#### Scenario: Render pending and processing states

- **GIVEN** 异步任务状态分别为待处理或处理中
- **WHEN** 页面展示任务
- **THEN** 页面 MUST 使用对应的统一状态文案和视觉状态
- **AND** 页面 MUST treat both states as active states that can be polled

#### Scenario: Render terminal states

- **GIVEN** 异步任务状态为已完成、已失败或已取消
- **WHEN** 页面展示任务
- **THEN** 页面 MUST 使用对应的统一终态文案和视觉状态
- **AND** 页面 MUST stop automatic polling for that task

#### Scenario: Represent partial success

- **GIVEN** 任务执行结束且成功数大于零、失败数大于零
- **WHEN** 页面展示任务结果
- **THEN** 页面 MUST show status as 已完成
- **AND** 页面 MUST show total count, success count, failed count, and available failure details
- **AND** 页面 MUST NOT introduce or display 部分成功 as a separate task status

### Requirement: Unified Common Page States

The admin frontend SHALL provide consistent loading, empty, forbidden, request failure, and retry interactions on the three supported async-task pages.

#### Scenario: Show loading state

- **GIVEN** 页面正在请求任务列表或任务详情
- **WHEN** 请求尚未完成
- **THEN** 页面 MUST show a loading state
- **AND** 页面 MUST prevent duplicate requests caused by repeated automatic triggers

#### Scenario: Show empty state

- **GIVEN** 任务查询成功但没有任务数据
- **WHEN** 页面完成渲染
- **THEN** 页面 MUST show the unified empty state
- **AND** 页面 MUST keep the page search or task creation entry available when the user has permission

#### Scenario: Handle forbidden response

- **GIVEN** 任务列表或详情接口 responds with HTTP 403
- **WHEN** 页面 handles the response
- **THEN** 页面 MUST show an explicit no-permission state
- **AND** 页面 MUST NOT automatically retry the request

#### Scenario: Retry transient request failure

- **GIVEN** a task list or detail request fails for a transient reason other than 403
- **WHEN** 页面 handles the response
- **THEN** 页面 MUST preserve already loaded task data and user input
- **AND** 页面 MUST provide an explicit retry action
- **AND** automatic polling MUST continue only after a successful retry or a subsequent successful refresh

### Requirement: Unified Task Progress Model

The admin frontend SHALL normalize task progress into task status, total count, success count, failed count, and failure details for device batch allocation, batch ordering, and export tasks.

#### Scenario: Display active task progress

- **GIVEN** a task is pending or processing
- **WHEN** task details are available
- **THEN** 页面 MUST display the current status and total count
- **AND** 页面 MUST display success count and failed count when returned
- **AND** 页面 MUST update the displayed values after each successful refresh

#### Scenario: Display failed task details

- **GIVEN** a task is failed or has failed items
- **WHEN** 页面 renders the task result
- **THEN** 页面 MUST display a safe failure summary when available
- **AND** 页面 MUST display failure details when the business detail API provides them

### Requirement: Task Creation And Recovery

The admin frontend SHALL persist the `task_id` returned by an async task creation request and use it to recover the task instead of creating a duplicate task after refresh or re-entry.

#### Scenario: Save task after creation

- **GIVEN** 用户确认设备批量分配、批量订购或导出操作
- **WHEN** task creation succeeds and returns `task_id`
- **THEN** 系统 MUST persist the task identifier for the corresponding business entry
- **AND** 系统 MUST start the unified task detail interaction for that task

#### Scenario: Recover task after page refresh

- **GIVEN** 当前业务入口存在已保存的 active `task_id`
- **WHEN** 用户刷新页面或重新进入该入口
- **THEN** 系统 MUST query the existing task detail using that `task_id`
- **AND** 系统 MUST NOT create another task automatically

#### Scenario: Clear task reference after terminal state

- **GIVEN** a recovered or newly created task reaches a terminal state
- **WHEN** 页面 handles the terminal task response
- **THEN** 系统 MUST stop polling
- **AND** 系统 MUST retain the result for display while allowing a later operation to create a new task

### Requirement: Visibility-Aware Incremental Polling

The admin frontend SHALL poll active async tasks at 2 seconds, 3 seconds, and 5 seconds after creation or refresh, then use an interval no longer than 10 seconds until the task reaches a terminal state.

#### Scenario: Poll active task with increasing delay

- **GIVEN** a task is in 待处理 or 处理中
- **WHEN** the previous task detail request succeeds and the task remains active
- **THEN** the next refresh MUST be scheduled after 2 seconds, then 3 seconds, then 5 seconds
- **AND** subsequent refreshes MUST NOT be more than 10 seconds apart

#### Scenario: Pause polling while page is hidden

- **GIVEN** an active task is being polled
- **WHEN** the browser page becomes not visible
- **THEN** the frontend MUST pause or cancel the pending poll
- **AND** the frontend MUST NOT issue automatic polling requests while the page remains hidden

#### Scenario: Refresh immediately when page becomes visible

- **GIVEN** an active task was paused because the page was hidden
- **WHEN** the page becomes visible again
- **THEN** the frontend MUST request the task detail immediately
- **AND** the frontend MUST resume the incremental polling schedule only if the task remains active

### Requirement: Safe Async Task Error Messaging

The admin frontend SHALL use a safe user-facing error summary for task failures and SHALL NOT expose a raw error code or low-level technical error as the primary user message.

#### Scenario: Show task failure summary

- **GIVEN** a failed task response contains `error_summary`
- **WHEN** 页面展示失败原因
- **THEN** 页面 MUST show `error_summary` as the primary failure message
- **AND** 页面 MUST NOT use `error_code` as the user-facing text

#### Scenario: Fallback when safe summary is absent

- **GIVEN** a failed task response does not contain a safe error summary
- **WHEN** 页面展示失败原因
- **THEN** 页面 MUST show a generic actionable failure message
- **AND** 页面 MUST keep the raw error code and technical error out of the primary user-facing message
