## 1. Contract And Types

- [ ] 1.1 确认 `POST /api/admin/bulk-purchases` 的 multipart 字段类型、文件字段格式和响应结构。
- [ ] 1.2 确认 `GET /api/admin/bulk-purchases/{task_id}` 的任务摘要字段、状态值、金额字段和错误字段。
- [ ] 1.3 确认 `GET /api/admin/bulk-purchases/{task_id}/items` 的逐行字段、分页结构和状态筛选参数。
- [x] 1.4 新增批量订购 API service、请求类型、任务摘要类型和逐行结果类型。
- [x] 1.5 明确 `request_id` 的生成、保存和重复提交响应处理规则。

## 2. Upload And Create

- [x] 2.1 新增批量订购入口和表单，支持选择代理商、支付方式和 Excel 文件。
- [x] 2.2 提供前端静态 Excel 模板下载，并限制上传文件类型和必要的文件状态。
- [x] 2.3 线下支付时显示整批支付凭证上传，钱包支付时隐藏或清理凭证字段。
- [x] 2.4 复用订单列表已有 `VoucherUpload` 组件展示凭证上传进度，上传未完成时禁止创建任务。
- [x] 2.5 创建请求携带 `shop_id`、`payment_method`、`file`、必要的 `voucher_file` 和 `request_id`。
- [x] 2.6 防止重复点击和重复提交，创建成功后保存 `task_id` 并进入任务详情。

## 3. Task Progress And Recovery

- [x] 3.1 展示任务号、状态、总数、成功数、失败数、金额汇总和安全错误摘要。
- [x] 3.2 按公共异步任务规则轮询待处理和处理中的任务，并在终态停止。
- [x] 3.3 页面刷新或通过任务 ID 重新进入时恢复任务详情，不重复创建批次。
- [x] 3.4 将部分成功展示为已完成终态，并同时展示成功数和失败数。
- [x] 3.5 展示钱包余额不足导致的逐行或后续行失败，不回滚已成功订单。

## 4. Item Results

- [x] 4.1 新增逐行结果表格，展示行号、资产、套餐编码、状态和错误原因。
- [x] 4.2 支持按逐行状态筛选和分页查询。
- [x] 4.3 失败原因优先展示后端安全错误文案，不直接展示底层技术错误。
- [x] 4.4 任务详情和逐行结果保持当前任务 ID、筛选条件和分页状态。

## 5. Permissions And Verification

- [x] 5.1 为批量订购创建、任务详情、逐行结果和模板下载配置独立权限。
- [ ] 5.2 验证一个批次只能提交一种支付方式，线下支付缺少凭证时不能提交。
- [ ] 5.3 验证重复提交复用 `request_id`，不会创建重复任务。
- [ ] 5.4 验证空文件、上传失败、任务失败、部分成功和钱包余额不足场景。
- [ ] 5.5 验证页面刷新恢复、任务终态停止轮询和逐行失败筛选。
- [x] 5.6 运行 `openspec validate add-bulk-purchase-upload-task --strict`、类型检查、lint 和构建。

## Implementation Notes

- 后端接口文档未随仓库提供，1.1、1.2、1.3 仍需联调确认精确金额字段、逐行字段和 multipart 文件格式；当前类型使用可选兼容字段。
- 5.2 至 5.5 需要接入真实后端后进行手工回归，当前已完成前端校验、权限、幂等键、恢复、轮询和筛选逻辑。
- 支付凭证复用 `src/components/business/VoucherUpload.vue`，提交 `voucher_file` 时使用该组件上传后返回的文件 key。
