feat: 产品迭代7月份
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 5m51s

This commit is contained in:
luo
2026-07-27 16:30:29 +08:00
parent cc6fc9243e
commit f0a2b84e53
75 changed files with 2926 additions and 534 deletions

View File

@@ -1,26 +1,26 @@
## 1. API Contracts And Types
- [ ] 1.1 扩展卡列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`
- [ ] 1.2 扩展设备列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`
- [ ] 1.3 将卡列表查询接入 `GET /api/admin/iot-cards/standalone` 并传递实名状态筛选参数。
- [x] 1.1 扩展卡列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`
- [x] 1.2 扩展设备列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`
- [x] 1.3 将卡列表查询接入 `GET /api/admin/iot-cards/standalone` 并传递实名状态筛选参数。
## 2. Card List
- [ ] 2.1 在卡列表筛选区新增“实名状态”的全部、已实名、未实名选项。
- [ ] 2.2 将选中的实名状态传递给卡列表查询,并在搜索、刷新、分页、导出中保留该条件。
- [ ] 2.3 在卡列表表格新增“实名状态”列,展示接口返回的 `real_name_status_name`
- [ ] 2.4 重置卡列表搜索时清空实名状态筛选。
- [x] 2.1 在卡列表筛选区新增“实名状态”的全部、已实名、未实名选项。
- [x] 2.2 将选中的实名状态传递给卡列表查询,并在搜索、刷新、分页、导出中保留该条件。
- [x] 2.3 在卡列表表格新增“实名状态”列,展示接口返回的 `real_name_status_name`
- [x] 2.4 重置卡列表搜索时清空实名状态筛选。
## 3. Device List
- [ ] 3.1 在设备列表筛选区新增“实名状态”的全部、已实名、未实名选项。
- [ ] 3.2 将选中的实名状态传递给 `GET /api/admin/devices`,并在搜索、刷新、分页、导出中保留该条件。
- [ ] 3.3 在设备列表表格新增“实名状态”列,直接展示接口返回的 `real_name_status_name`,不遍历绑定卡计算状态。
- [ ] 3.4 重置设备列表搜索时清空实名状态筛选。
- [x] 3.1 在设备列表筛选区新增“实名状态”的全部、已实名、未实名选项。
- [x] 3.2 将选中的实名状态传递给 `GET /api/admin/devices`,并在搜索、刷新、分页、导出中保留该条件。
- [x] 3.3 在设备列表表格新增“实名状态”列,直接展示接口返回的 `real_name_status_name`,不遍历绑定卡计算状态。
- [x] 3.4 重置设备列表搜索时清空实名状态筛选。
## 4. Verification
- [ ] 4.1 验证卡列表“全部”“已实名”“未实名”分别不传、传 `1`、传 `0`,且状态列显示接口名称。
- [ ] 4.2 验证设备列表“全部”“已实名”“未实名”分别不传、传 `1`、传 `0`,且状态列直接显示设备接口名称。
- [ ] 4.3 验证两个列表在分页切换、刷新和导出时保留实名状态筛选,重置后清空该条件。
- [ ] 4.4 运行相关类型检查、lint 或构建验证。
- [x] 4.4 运行相关类型检查、lint 或构建验证。

View File

@@ -18,5 +18,5 @@
- [ ] 4.1 验证活跃退款资产创建换货时显示“该资产存在退款申请”或后端等价业务原因,且不创建换货单。
- [ ] 4.2 验证已拒绝、撤销或处理完成退款的资产按后端结果可继续创建换货。
- [ ] 4.3 验证失败后保留表单并可更换资产重新提交。
- [x] 4.3 验证失败后保留表单并可更换资产重新提交。
- [x] 4.4 运行相关前端校验,并执行 `openspec validate update-exchange-refund-interception-feedback --strict`

View File

@@ -1,21 +1,21 @@
## 1. API Contract And Types
- [ ] 1.1 将换货列表查询类型中的通用 `identifier` 替换为可选的 `old_asset_keyword``new_asset_keyword`
- [ ] 1.2 扩展换货列表项类型,支持 `old_asset_type``old_asset_id``old_asset_identifier``new_asset_type``new_asset_id``new_asset_identifier``status``status_name`
- [x] 1.1 将换货列表查询类型中的通用 `identifier` 替换为可选的 `old_asset_keyword``new_asset_keyword`
- [x] 1.2 扩展换货列表项类型,支持 `old_asset_type``old_asset_id``old_asset_identifier``new_asset_type``new_asset_id``new_asset_identifier``status``status_name`
## 2. Exchange List Search
- [ ] 2.1 将换货管理列表筛选区的“资产标识符”替换为“旧资产”和“新资产”输入框。
- [ ] 2.2 查询、刷新和分页时保留并传递非空的 `old_asset_keyword``new_asset_keyword`,不再发送 `identifier`
- [ ] 2.3 重置搜索条件时清空新旧资产关键词,后续请求不发送这两个参数。
- [ ] 2.4 保留用户输入的 ICCID、接入号、虚拟号、IMEI 或 SN 原始值,不在前端转换后再传递给后端。
- [x] 2.1 将换货管理列表筛选区的“资产标识符”替换为“旧资产”和“新资产”输入框。
- [x] 2.2 查询、刷新和分页时保留并传递非空的 `old_asset_keyword``new_asset_keyword`,不再发送 `identifier`
- [x] 2.3 重置搜索条件时清空新旧资产关键词,后续请求不发送这两个参数。
- [x] 2.4 保留用户输入的 ICCID、接入号、虚拟号、IMEI 或 SN 原始值,不在前端转换后再传递给后端。
## 3. Exchange List Display
- [ ] 3.1 增加旧资产类型、旧资产标识、新资产类型、新资产标识四个独立列表列。
- [ ] 3.2 根据后端资产类型显示“物联网卡”或“设备”,并原样显示对应后端资产标识。
- [ ] 3.3 状态列优先展示后端 `status_name`,缺失时显示稳定占位内容。
- [ ] 3.4 新资产字段在未分配时显示稳定占位内容,不与旧资产字段混用。
- [x] 3.1 增加旧资产类型、旧资产标识、新资产类型、新资产标识四个独立列表列。
- [x] 3.2 根据后端资产类型显示“物联网卡”或“设备”,并原样显示对应后端资产标识。
- [x] 3.3 状态列优先展示后端 `status_name`,缺失时显示稳定占位内容。
- [x] 3.4 新资产字段在未分配时显示稳定占位内容,不与旧资产字段混用。
## 4. Verification
@@ -23,4 +23,4 @@
- [ ] 4.2 验证两个资产关键词均为空时不传筛选参数,重置后保持相同行为。
- [ ] 4.3 验证旧资产和新资产类型、标识符分别显示IoT 卡显示 ICCID、设备显示设备号。
- [ ] 4.4 验证卡的 ICCID、接入号或虚拟号关键词均由后端按输入所在的旧/新资产条件命中,前端不转换输入值。
- [ ] 4.5 运行相关类型检查、lint 或构建验证。
- [x] 4.5 运行相关类型检查、lint 或构建验证。

View File

@@ -0,0 +1,42 @@
## Context
七月迭代后端实现已形成一份统一的前端联调说明,但需求横跨多个后台业务域,并同时涉及 H5/C 端接口。若不先固定边界,前端容易继续依赖旧字段、重复计算服务端事实,或误把 C 端工作纳入后台改造。
## Goals / Non-Goals
- Goals: 固定后台页面的调用顺序、字段来源、权限边界、金额单位、异步任务和错误处理规则。
- Goals: 明确 H5/C 端依赖并标注为外部范围,不在本提案任务中实施。
- Non-Goals: 不新增后端接口,不修改数据库,不实现企微/Gateway/Redis/Asynq/对象存储服务端逻辑。
- Non-Goals: 不修改 H5 或 C 端页面、组件和调用代码。
## Decisions
- Decision: 后端返回值是业务事实来源。前端不得自行推导实名状态、支付方式、预计到期、可用金额、欠款、审批状态或异步任务状态。
- Decision: 金额统一以分传输和计算,展示层才转换为元;信用和资金更新必须携带服务端返回的 `version`
- Decision: H5/C 端接口在规格中单独列为外部依赖,后台只负责在需要时保持接口契约一致。
- Decision: 企微审批继续由原退款/线下充值业务入口触发,后台只读展示 `approval_provider``approval_status``approval_status_name`,不恢复旧人工审批按钮。
- Decision: 设备批量分配复用设备导入任务页面和任务外壳,通过 `operation_type` 区分分配代理与设置套餐系列。
- Decision: 系列套餐授权使用现有 `packages[]` 数组完成多选,授权详情中的 `package_id` 用于已授权标记,套餐列表中的公司成本价与授权成本价分开使用。
- Decision: `docs/所需接口文档` 是本变更的接口契约索引;页面 API 类型、请求参数、枚举和响应字段必须以对应模块文档为准,不从七月说明中自行扩展路径。
- Decision: 文件类业务统一采用 `POST /api/admin/storage/upload-url` 获取预签名 URL直传成功后仅把 `file_key` 传给批量订购或设备分配接口。
- Decision: 批量订购、设备分配和导出均保存服务端返回的任务 ID页面恢复时查询原任务终态后停止轮询不能因刷新或超时重复创建。
## Risks / Trade-offs
- 接口 DTO 若未按说明返回,页面无法可靠展示审批人、历史资产标识或新旧字段;通过联调清单阻断实现前确认。
- 设备批量分配接口文档已明确任务列表和详情仅平台用户可操作,前端不得向代理账号展示任务入口或通过前端绕过权限。
- H5/C 端不在本次实现范围,后台只能依赖后端提供的最终字段,跨端验收需要单独安排。
- 部分接口文档只给出字段模型,缺少业务错误码、权限编码和分页默认值;这些列入待确认清单。
## Migration Plan
1. 先确认接口待补充项和后台权限编码。
2. 按任务清单分模块适配后台页面和 API 类型。
3. 完成后台接口 Mock/联调、权限组合和错误场景验收。
4. H5/C 端另行创建或关联变更,不在本变更中合并实现。
## Open Questions
- 退款和代理充值详情是否需要直接返回企微审批节点人员列表?
- 各新增后台页面和按钮的最终权限编码是什么?
- 批量任务、导出任务、企微审批和 Gateway 超时的稳定错误码及重试语义是什么?

View File

@@ -0,0 +1,23 @@
# Change: 对接七月迭代后台实现与接口契约
## Why
最新的七月迭代实现说明明确了后端已完成的接口、字段语义、前端调用顺序和联调边界。当前后台页面仍需要按这些最新契约完成筛选、展示、权限、审批、批量任务、导出和代理资金能力的统一对接,避免继续使用旧字段或前端自行推导业务规则。
## What Changes
-`00-七月迭代实现与接口对接说明.md` 更新后台管理端的接口调用和页面展示契约。
-`docs/所需接口文档/01-店铺.md``21-设备批量分配.md` 为接口参数、响应字段、枚举、权限和错误语义的具体来源。
- 对资产、店铺、订单、换货、套餐、资金、系列授权、审批、通知、批量任务、导出和 Gateway 相关页面补齐前端适配要求。
- 统一使用后端返回的实名策略、支付方式、预计到期、审批状态、金额计算结果和任务状态,不在前端重复推导。
- 补齐 CSV 上传模板、异步任务恢复、权限按钮、错误处理和并发冲突处理要求。
- 明确预签名上传先取 `file_key`、再调用批量业务接口的两阶段流程,并固定批量订购、设备分配和导出任务的终态处理规则。
- **不实施 H5/C 端页面改动**,但在规格和联调清单中标注其依赖的接口及外部工作项。
- **不实施后端接口、数据库、Worker、企微回调、Gateway 和对象存储改造**;本变更只描述后台前端联调所需的适配边界。
## Impact
- Affected specs: `july-iteration-frontend-integration`
- Affected code: 后台资产、店铺、订单、换货、套餐、代理资金、系列授权、审批配置、通知、批量任务和导出页面
- External follow-up: H5/C 端认证限制、实名流程、支付按钮、C 端订单续费、C 端通知和 C 端资产展示
- Approval gate: 接口待确认项完成前不进入大范围实现

View File

@@ -0,0 +1,193 @@
## ADDED Requirements
### Requirement: Backend-first field semantics
The admin frontend SHALL use backend-provided business facts for real-name status, payment methods, estimated expiry, approval status, task status, balances, available amounts, debt amounts, and asset identifiers. The frontend MUST NOT infer or recalculate these values from partial data.
#### Scenario: Payment methods are displayed from the API
- **WHEN** the asset or recharge API returns `allowed_payment_methods`
- **THEN** the admin or related integration UI uses that list instead of hard-coded payment rules
#### Scenario: Financial amounts are displayed from the API
- **WHEN** a fund or credit response returns calculated balances
- **THEN** the frontend displays the returned values in fen-based data and only converts them for presentation
### Requirement: Admin asset and shop integration
The admin frontend SHALL support the confirmed July filters and fields for shops, IoT cards, devices, orders, exchanges, and assets, including contact-phone search, salesperson data, client login restriction, real-name filters, separate old/new exchange searches, asset identifiers, and estimated final expiry.
#### Scenario: Exchange assets are searched independently
- **WHEN** a user enters old and new asset search terms
- **THEN** the frontend sends `old_asset_keyword` and `new_asset_keyword` independently and preserves AND filtering semantics
#### Scenario: A shop login restriction is edited
- **WHEN** an authorized user updates a shop
- **THEN** the request includes the optional `client_login_disabled` value and the list/detail views display the returned value
### Requirement: Package allocation and series authorization
The admin frontend SHALL use the existing package and series authorization APIs for default expiry settings, override expiry settings, package multi-selection, authorization detail lookup, and package add/update/remove operations.
#### Scenario: A series authorization is edited
- **WHEN** a user opens an existing authorization
- **THEN** the frontend queries by authorization record ID, marks authorized package IDs, and keeps company cost price separate from authorization cost price
#### Scenario: Authorized packages are updated
- **WHEN** a user submits package changes
- **THEN** the frontend sends a 1100 item `packages[]` array, uses `remove=true` for removals, and loads additional package pages when the series contains more than 100 packages
### Requirement: Credit and system configuration integration
The admin frontend SHALL integrate role default credit, shop actual credit, fund summary, and controlled system configuration APIs using fen-based amounts, server-calculated values, optimistic-lock versions, and registered configuration validation metadata.
#### Scenario: A shop credit limit update conflicts
- **WHEN** the credit update is rejected because the wallet `version` is stale
- **THEN** the frontend refreshes the latest fund summary and asks the user to retry with the latest version
#### Scenario: A configuration is read-only
- **WHEN** a configuration item is returned with `readonly=true`
- **THEN** the frontend disables its editing control and does not submit an update for that item
### Requirement: WeCom approval status integration
The admin frontend SHALL provide the confirmed WeCom configuration workflow and SHALL display business approval status as read-only for refund and offline recharge records when the approval provider is WeCom or an approval instance exists.
#### Scenario: A WeCom business record is awaiting approval
- **WHEN** a refund or offline recharge record has `approval_provider=wecom` or an `approval_instance_id`
- **THEN** the frontend displays the backend approval status and hides legacy manual approval actions
#### Scenario: A template mapping is rejected
- **WHEN** the backend rejects a scene template mapping
- **THEN** the frontend preserves the submitted form values and displays the backend validation message
### Requirement: Notifications, asynchronous tasks, exports, and Gateway controls
The admin frontend SHALL integrate low-balance notifications, expiring asset summaries, batch purchase tasks, export tasks, card speed tiers, and device allocation tasks according to the confirmed task, CSV, datasource, and timeout semantics.
#### Scenario: A batch task is restored
- **WHEN** a user reloads or re-enters a batch purchase or device allocation page
- **THEN** the frontend queries the existing task detail using the saved task identifier and does not create a duplicate task
#### Scenario: A speed tier is selected
- **WHEN** a user operates on an IoT card
- **THEN** the frontend submits a fixed speed-tier code from `-1` through `8`; a device page does not expose a speed-tier control
### Requirement: H5 and C-end work is explicitly external
The July integration specification SHALL identify H5/C-end changes as external follow-up work. This change MUST NOT modify H5/C-end pages or their API call implementations.
#### Scenario: A requirement depends on C-end behavior
- **WHEN** a requirement involves C-end login restriction, real-name flow, payment methods, asset display, order renewal, or C-end notifications
- **THEN** the item is marked as an external dependency and excluded from this change's implementation tasks
### Requirement: Permission and error boundaries
The admin frontend SHALL apply confirmed permission codes to new pages, buttons, and row actions, enforce data isolation in the UI, and present stable user-facing errors for authentication, authorization, validation, timeout, conflict, and unknown-result cases.
#### Scenario: A user lacks an action permission
- **WHEN** the current account does not have the configured permission code
- **THEN** the corresponding page action is hidden or disabled and the frontend does not invoke the API
#### Scenario: An asynchronous operation has an unknown result
- **WHEN** a task or Gateway operation times out with an unknown result
- **THEN** the frontend preserves the current data, shows a safe status message, and provides a refresh or manual verification path instead of blindly retrying
### Requirement: Documented API contract alignment
The admin frontend SHALL implement the July integration against the documented API paths and request/response contracts. The documented interface files under `docs/所需接口文档/` SHALL be treated as the source of truth for parameter names, enum values, nullable fields, pagination, permissions, and HTTP error semantics.
#### Scenario: A page loads a documented resource
- **WHEN** a July page queries or mutates a resource
- **THEN** it uses the corresponding documented `/api/admin` endpoint and sends the documented parameter names without translating them to legacy frontend names
#### Scenario: A response contains a nullable or enumerated field
- **WHEN** a documented response returns a nullable field, numeric status, string enum, or `*_name` display field
- **THEN** the frontend preserves the nullable state, uses the documented enum values, and prefers the backend display name instead of inventing a local label
#### Scenario: An API rejects a request
- **WHEN** a documented endpoint returns `400`, `401`, `403`, or `500`
- **THEN** the frontend applies the shared authentication, authorization, validation, server-error, and retry-safe handling without exposing raw transport details as the user-facing message
### Requirement: File upload and batch task contract
The admin frontend SHALL use `POST /api/admin/storage/upload-url` for file-backed July operations, upload to the returned `upload_url` with the requested content type, and pass only the returned `file_key` to the business endpoint. Batch purchase and device allocation CSVs SHALL be UTF-8 single-column files, accept an optional UTF-8 BOM, stay within 10 MB and 1000 data rows, and preserve identifiers as text.
#### Scenario: A batch purchase is submitted
- **WHEN** the user selects one package and one payment method and uploads a valid CSV
- **THEN** the frontend calls `POST /api/admin/asset-package-batch-orders` with `file_key`, `package_id`, `payment_method`, and, for offline payment, 15 `voucher_keys`
#### Scenario: A device allocation is submitted
- **WHEN** a platform user selects an allocation target and uploads a valid device CSV
- **THEN** the frontend calls `POST /api/admin/devices/import/allocations` with `file_key`, `operation_type` set to `assign_shop` or `assign_series`, and the selected `target_id`
#### Scenario: A batch task is resumed
- **WHEN** the page is reloaded while a task is non-terminal
- **THEN** the frontend queries the saved task ID, displays the backend `status_name` and progress/result counts, stops polling at the documented terminal state, and never creates a second task
### Requirement: WeCom configuration API workflow
The admin frontend SHALL implement the documented WeCom configuration sequence: list or save applications through `/api/admin/wecom/applications`, test the application, synchronize and query visible members, set the default creator, bind system accounts through `/api/admin/accounts/{account_id}/wecom-binding`, and save or query the two supported scene mappings.
#### Scenario: A WeCom application is configured
- **WHEN** a super administrator saves valid application credentials
- **THEN** the frontend refreshes the application, allows connection testing, and clearly distinguishes `data.success=true` for access-token acquisition from completed member, template, and callback configuration
#### Scenario: A default creator is selected
- **WHEN** the user sets a default creator
- **THEN** the frontend only submits a `userid` selected from the latest synchronized visible-member list and preserves the real local submitter in business records
#### Scenario: A scene mapping is validated
- **WHEN** the user saves `refund_approval` or `offline_recharge_approval`
- **THEN** the frontend submits `application_id`, `template_id`, `control_mapping`, and `status`, preserves input on validation failure, and displays the returned verification/status fields after success
### Requirement: Approval and financial business API contract
The admin frontend SHALL use the documented refund and agent-recharge APIs for business creation and read-only approval tracking. Amounts and voucher keys SHALL follow the documented units and cardinality, and a record with `approval_provider=wecom` or `approval_instance_id` SHALL not expose legacy manual approval actions.
#### Scenario: An offline agent recharge is created
- **WHEN** a platform user submits an offline recharge
- **THEN** the frontend calls `POST /api/admin/agent-recharges` with the target `shop_id`, amount in fen, `payment_method=offline`, and 15 voucher keys
#### Scenario: A refund is awaiting WeCom approval
- **WHEN** `GET /api/admin/refunds` or `GET /api/admin/refunds/{id}` returns a WeCom approval instance
- **THEN** the frontend displays `approval_status_name`, `submitter_name`, and documented amount fields as read-only and does not show approve/reject actions
#### Scenario: Approval submission has an unknown result
- **WHEN** `approval_status=8` or the documented status name indicates an unknown submission result
- **THEN** the frontend does not recreate the business record and offers refresh or manual verification instead
### Requirement: Documented device allocation permissions
The admin frontend SHALL enforce the documented permission boundary for device allocation task list and detail APIs. Because those APIs are documented as platform-only, agent and enterprise accounts SHALL not see the allocation task entry or be allowed to invoke the task list/detail endpoints from the UI.
#### Scenario: A non-platform user opens device allocation
- **WHEN** an agent or enterprise account loads the device allocation area
- **THEN** the frontend hides the entry and does not call `/api/admin/devices/import/tasks` or `/api/admin/devices/import/tasks/{id}`

View File

@@ -0,0 +1,61 @@
## 1. Contract and API Types
- [x] 1.1 根据 `docs/所需接口文档/01-店铺.md``21-设备批量分配.md` 以及最新说明核对所有纳入本期范围的 API 类型。
- [x] 1.2 补齐 `purchase_role``asset_identifier``effective_realname_policy``allowed_payment_methods`、预计到期和换货链路字段。
- [x] 1.3 补齐退款、代理充值和换货的提交人及审批状态字段。
- [x] 1.4 补齐系统配置、批量任务、导出任务、Gateway 限速和设备分配任务字段。
- [x] 1.5 为金额、版本号、枚举和 nullable 字段增加明确的前端类型约束。
## 2. Asset, Shop, Order, and Exchange Pages
- [x] 2.1 店铺列表接入联系电话精确查询、业务员筛选和 `client_login_disabled` 展示/编辑。
- [x] 2.2 资产卡和设备列表接入 `real_name_status` 筛选及状态展示。
- [x] 2.3 实名策略页面接入单条和最多 500 条批量修改,并处理全成全败结果。
- [x] 2.4 换货列表拆分旧资产和新资产搜索参数,并展示新旧资产信息。
- [x] 2.5 资产、订单和 C 端相关后台页面展示正确的订单渠道及资产标识。
- [x] 2.6 展示预计最终到期时间并按后端临期字段高亮。
- [x] 2.7 退款中资产创建换货时展示后端业务错误,不调用企微实时查询。
- [x] 2.8 历史订单或当前资产续费继续调用现有订单创建接口,不新增续费接口。
## 3. Package, Fund, and Authorization Pages
- [x] 3.1 套餐页面传递 `expiry_base` 并展示默认生效条件。
- [x] 3.2 套餐分配页面传递 `expiry_base_override` 并展示最终生效条件。
- [x] 3.3 系列授权页面支持 1100 个套餐多选,创建使用 `packages[]`
- [x] 3.4 系列授权编辑使用授权记录 ID 查询详情,区分公司成本价和授权成本价。
- [x] 3.5 系列授权套餐管理使用 `remove=true` 删除项,并继续分页加载超过 100 个套餐的系列。
- [x] 3.6 角色默认信用、店铺实际信用和资金概况统一使用分单位字段。
- [x] 3.7 店铺调额携带资金 `version`,并处理并发冲突刷新和重试。
- [x] 3.8 系统配置页面接入卡/设备支付方式配置,提交 JSON 数组字符串并保留至少一种支付方式。
## 4. WeCom Approval and Business Status
- [x] 4.1 实现企微应用配置页的应用列表、保存、测试连接和状态展示。
- [x] 4.2 实现成员同步、成员查询、默认发起人设置和账号绑定入口。
- [x] 4.3 实现退款和线下代充值场景模板映射配置及后端校验错误保留输入。
- [x] 4.4 退款、代理充值列表/详情只读展示审批状态,隐藏企微业务的旧人工审批按钮。
- [x] 4.5 对提交中、审批中、已通过、已拒绝、已撤销、通过后撤销、已删除、提交失败和提交结果未知状态使用后端名称。
## 5. Notifications, Async Tasks, Exports, and Gateway
- [x] 5.1 接入后台低余额通知列表、未读数和已读操作。
- [x] 5.2 接入临期资产列表、统计摘要、优先级和高亮规则。
- [x] 5.3 批量订购使用 UTF-8 单列 CSV、上传用途、套餐和支付方式独立选择。
- [x] 5.4 批量订购任务展示逐行成功/失败结果并支持任务详情恢复。
- [x] 5.5 导出任务支持本期六类 datasource、筛选条件 `query`、统一任务状态、进度和完成后 24 小时下载链接;保留接口文档中已有的设备/订单场景兼容性。
- [x] 5.6 卡页面接入 ICCID 固定限速档位 `-18`,设备页面不展示限速入口。
- [x] 5.7 设备批量分配复用导入任务页面,支持 `assign_shop``assign_series` 两种 operation_type。
- [x] 5.8 提供两份静态 UTF-8 CSV 模板校验单列、10MB 和最多 1000 行限制。
## 6. Permissions, Errors, and Verification
- [x] 6.1 为新增页面、按钮和行操作接入最终确认的权限编码。
- [x] 6.2 统一处理 400、401、403、业务错误、超时和结果未知不使用底层错误直接作为用户文案。
- [x] 6.3 验证代理数据隔离、平台权限、敏感字段脱敏和财务操作审计入口。
- [ ] 6.4 完成后台页面的接口联调、权限组合、空数据、错误、并发冲突和任务恢复验收。
## 7. Explicitly Out Of Scope
- H5/C 端登录限制、实名流程、支付按钮、资产详情、订单续费和 C 端通知不在本次实现任务内。
- H5 首页隐藏设备下 ICCID 仍按最新说明标记为不做。
- H5/C 端相关接口仅作为后台联调依赖记录,不在本变更中修改页面或调用代码。

View File

@@ -1,33 +1,33 @@
## 1. Contract And Model
- [ ] 1.1 确认设备批量分配、批量订购和导出任务创建响应均返回稳定的 `task_id`
- [ ] 1.2 确认三类任务按 `task_id` 查询详情的接口路径、状态字段和失败明细字段。
- [x] 1.1 确认设备批量分配、批量订购和导出任务创建响应均返回稳定的 `task_id`
- [x] 1.2 确认三类任务按 `task_id` 查询详情的接口路径、状态字段和失败明细字段。
- [x] 1.3 新增统一任务状态、进度、错误摘要和任务恢复类型,兼容各业务字段别名。
- [x] 1.4 更新导出任务列表和详情类型,补充 `task_id``total_count``success_count``failed_count``error_code``error_summary``updated_at`
## 2. Shared Interaction
- [ ] 2.1 实现统一加载中、空数据、无权限、接口失败和重试状态的展示规则。
- [x] 2.1 实现统一加载中、空数据、无权限、接口失败和重试状态的展示规则。
- [x] 2.2 实现五态任务状态映射,并明确终态为已完成、已失败或已取消。
- [ ] 2.3 实现统一任务进度展示,支持总数、成功数、失败数和失败明细。
- [ ] 2.4 实现任务创建后的 `task_id` 持久化、刷新恢复和失效任务清理。
- [x] 2.3 实现统一任务进度展示,支持总数、成功数、失败数和失败明细。
- [x] 2.4 实现任务创建后的 `task_id` 持久化、刷新恢复和失效任务清理。
- [x] 2.5 实现 2 秒、3 秒、5 秒递增且最大 10 秒的轮询调度。
- [x] 2.6 实现页面不可见暂停轮询、恢复可见立即刷新和组件卸载清理。
## 3. Business Pages
- [ ] 3.1 接入设备批量分配页面,创建成功后进入统一任务交互流程。
- [ ] 3.2 接入批量订购页面,创建成功后进入统一任务交互流程。
- [x] 3.1 接入设备批量分配页面,创建成功后进入统一任务交互流程。
- [x] 3.2 接入批量订购页面,创建成功后进入统一任务交互流程。
- [x] 3.3 接入导出任务列表和详情页面,统一展示任务进度、失败摘要和更新时间。
- [ ] 3.4 保证部分成功任务仍展示为已完成,并显示成功数与失败数,不引入新状态。
- [ ] 3.5 保证页面刷新或重新进入时恢复任务,不重复提交创建请求。
- [x] 3.4 保证部分成功任务仍展示为已完成,并显示成功数与失败数,不引入新状态。
- [x] 3.5 保证页面刷新或重新进入时恢复任务,不重复提交创建请求。
## 4. Error And Permission Handling
- [x] 4.1 403 响应展示无权限状态并停止自动重试。
- [x] 4.2 瞬时接口失败保留已有任务数据和用户输入,并提供明确的手动重试入口。
- [x] 4.3 任务失败优先展示 `error_summary`,不直接展示 `error_code` 或底层技术错误。
- [ ] 4.4 验证无权限用户无法看到或触发对应批量操作、任务详情和重试操作。
- [x] 4.4 验证无权限用户无法看到或触发对应批量操作、任务详情和重试操作。
## 5. Verification
@@ -39,6 +39,6 @@
## Implementation Notes
- 设备批量分配当前仍由 `/api/admin/devices/allocate` 同步返回结果,未返回 `task_id`,因此未接入异步轮询
- 当前订单页面仅提供单笔订单创建,仓库中未发现批量订购创建接口或任务详情接口,因此未新增虚构的批量任务流程
- 设备批量分配和批量订购需待后端补充异步任务创建及详情契约后继续实施 1.1、1.2、3.1、3.2、3.4、3.5、4.4 及相关测试
- 设备批量分配使用 `/api/admin/devices/import/allocations` 创建任务,并复用设备任务详情接口及统一轮询恢复逻辑
- 批量订购使用文件 key 创建任务,创建成功后通过 `task_id` 路由参数和持久化状态恢复任务详情
- 真实后端环境下的五态、权限和并发回归测试仍需在联调环境执行