fix: 回调配置, 调整信用位置, 套餐
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 6m55s

This commit is contained in:
luo
2026-07-29 18:20:42 +08:00
parent 4394ae0f78
commit 17d2eeebc5
39 changed files with 2687 additions and 1532 deletions

View File

@@ -191,3 +191,129 @@ The admin frontend SHALL enforce the documented permission boundary for device a
- **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}`
### Requirement: Agent Wallet Online Recharge Contract
The admin frontend SHALL support the documented agent wallet online QR recharge flow through `/api/admin/agent-recharges/payment-methods` and `/api/admin/agent-recharges`. The available payment methods and amount limits SHALL come from the payment-methods response; the online create request SHALL contain only `amount` in integer fen, `payment_method` from the returned methods, and a required `request_id`. Online agent recharge requests MUST NOT send `shop_id`, `payment_voucher_key`, `remark`, merchant credentials, or payment configuration identifiers.
#### Scenario: Load available online payment methods
- **WHEN** an agent opens the online recharge dialog
- **THEN** the frontend calls `GET /api/admin/agent-recharges/payment-methods`
- **AND** it displays only the returned `methods` values (`wechat` and/or `alipay`)
- **AND** it validates the integer-fen amount against the returned `min_amount` and `max_amount`
#### Scenario: No online payment method is available
- **WHEN** the payment-methods response returns an empty `methods` array
- **THEN** the frontend hides or disables the submit action
- **AND** it displays that no online payment method is currently available
- **AND** it does not call the online create endpoint
#### Scenario: Create an online QR recharge
- **WHEN** an authorized agent submits a valid online recharge
- **THEN** the frontend calls `POST /api/admin/agent-recharges` with `amount`, `payment_method`, and `request_id`
- **AND** it converts the displayed yuan amount to an integer amount in fen before submission
- **AND** it uses the returned `recharge_id` and does not derive the target shop or wallet from user-editable form fields
#### Scenario: Render the returned QR content
- **WHEN** online recharge creation succeeds with a non-empty `qr_content`
- **THEN** the frontend passes `qr_content` unchanged to the QR-code component
- **AND** it does not parse, concatenate, replace, upload, persist, or log the QR content
### Requirement: Idempotent Online Recharge Submission
The frontend SHALL preserve one `request_id` for the lifetime of one active online recharge submission. A timeout or network interruption MAY retry the same submission once with the same `request_id`, but a user-initiated new recharge MUST generate a new request ID. A conflict caused by reusing the same request ID with a different amount or payment method SHALL preserve the existing form state and require an explicit new recharge attempt.
#### Scenario: Retry after an uncertain create result
- **WHEN** the online create request times out or the network disconnects
- **THEN** the frontend retries at most once with the original `request_id`
- **AND** it does not create a new `request_id` or blindly open a second recharge dialog
#### Scenario: Start a new recharge after closing the dialog
- **WHEN** the user closes the QR dialog and clicks online recharge again
- **THEN** the frontend creates a new `request_id`
- **AND** the new amount and payment method are treated as a new active submission
#### Scenario: Reused request ID conflicts
- **WHEN** the backend rejects a request because the same `request_id` is paired with different recharge parameters
- **THEN** the frontend displays the backend business message
- **AND** it does not overwrite the original request or automatically submit another amount
### Requirement: Online Payment And Wallet Arrival Polling
The online QR recharge dialog SHALL poll only the documented local payment-status endpoint `GET /api/admin/agent-recharges/{id}/payment-status`. While the QR dialog is visible and the recharge is non-terminal, the frontend SHALL poll at approximately three-second intervals. The frontend SHALL stop polling when the dialog is hidden, the page is not visible, or the recharge status is `3` (completed), `4` (closed), `5` (refunded), or `6` (rejected). It MUST treat `status=2` as third-party payment completed but wallet arrival still processing; only `status=3` permits refreshing the wallet balance and recharge list.
#### Scenario: Payment is waiting for the user
- **WHEN** payment-status returns `status=1` and `payment_status=0`
- **THEN** the dialog displays that the user is waiting to scan and pay
- **AND** polling continues while the dialog is visible
#### Scenario: Payment is received but wallet arrival is processing
- **WHEN** payment-status returns `status=2` and `payment_status=1`
- **THEN** the dialog displays payment success and wallet arrival processing
- **AND** the frontend does not increase or refresh the wallet balance as completed
- **AND** polling continues
#### Scenario: Wallet arrival completes
- **WHEN** payment-status returns `status=3`
- **THEN** the frontend displays that the recharge has arrived
- **AND** it stops polling
- **AND** it refreshes the current wallet balance and recharge list
#### Scenario: Online recharge reaches a terminal failure state
- **WHEN** payment-status returns `status=4`, `status=5`, or `status=6`
- **THEN** the frontend displays the backend status name or an appropriate failure message
- **AND** it stops polling without automatically creating a replacement recharge
### Requirement: Recharge Source And Operation Boundaries
The recharge list and detail pages SHALL use `recharge_source` as the only business branch: `agent_online` for agent online self-recharge and `platform_offline` for platform offline代充. They SHALL prefer `recharge_source_name` for display and use the documented list filters `shop_id`, `status`, `recharge_source`, `start_date`, and `end_date`. Online records SHALL show payment information and payment/completion timestamps while hiding offline vouchers and manual approval operations. Offline records SHALL show vouchers, remarks, submitter, and approval status; they SHALL not show QR content or invoke the online payment-status endpoint.
#### Scenario: Filter online recharge records
- **WHEN** a user selects online recharge source or status filters
- **THEN** the frontend requests `GET /api/admin/agent-recharges` with the documented filter names and values
- **AND** it displays the backend recharge source name, amount, payment method, status, submitter, and timestamps
#### Scenario: Display a platform offline recharge
- **WHEN** a platform user opens a record with `recharge_source=platform_offline`
- **THEN** the detail view displays the payment voucher, remark, submitter, and approval status
- **AND** it does not render a QR code or start payment-status polling
#### Scenario: Confirm or reject an offline recharge
- **WHEN** a pending offline recharge has no WeCom approval provider or approval instance
- **THEN** an authorized platform user MAY confirm it through `POST /api/admin/agent-recharges/{id}/offline-pay` with `operation_password`
- **AND** an authorized platform user MAY reject it through `POST /api/admin/agent-recharges/{id}/reject` with a required `rejection_reason` of at most 500 characters
#### Scenario: WeCom approval controls the offline record
- **WHEN** an offline recharge has `approval_provider=wecom` or an `approval_instance_id`
- **THEN** the frontend displays approval progress as read-only
- **AND** it hides confirm and reject operations
### Requirement: Agent Recharge Export Permissions
The agent recharge list SHALL show its export entry only with `agent_recharge:export`. The export-task page SHALL protect the `agent_recharge` detail and download operations with `export_task:agent_recharge_detail` and `export_task:agent_recharge_download`, respectively. The frontend SHALL hide unauthorized controls and SHALL NOT invoke the corresponding API as a fallback.
#### Scenario: An authorized user exports agent recharges
- **WHEN** the current account has `agent_recharge:export`
- **THEN** the agent recharge page displays the export entry and opens the `agent_recharge` export flow
#### Scenario: An unauthorized user accesses export actions
- **WHEN** the current account lacks an export permission
- **THEN** the related entry, detail action, or download action is hidden
- **AND** the frontend does not call the export-task detail or download endpoint