feat: 退款充值换货列表提交人与审批摘要
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m20s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 7m20s
This commit is contained in:
@@ -23,7 +23,7 @@
|
|||||||
## Risks / Trade-offs
|
## Risks / Trade-offs
|
||||||
|
|
||||||
- 后端未返回 `real_name_status_name` 时无法满足状态名称展示契约 -> 联调时校验列表响应字段,并将该字段设为必需的列表类型字段。
|
- 后端未返回 `real_name_status_name` 时无法满足状态名称展示契约 -> 联调时校验列表响应字段,并将该字段设为必需的列表类型字段。
|
||||||
- 卡列表当前存在不同的查询实现 -> 实施时确认并统一至本提案指定的 `GET /api/admin/iot-cards` 契约,避免筛选参数发往不支持的接口。
|
- 卡列表实名认证筛选依赖单卡列表接口 -> 实施时确保筛选参数发往 `GET /api/admin/iot-cards/standalone`。
|
||||||
|
|
||||||
## Migration Plan
|
## Migration Plan
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
## What Changes
|
## What Changes
|
||||||
|
|
||||||
- 卡列表和设备列表的筛选区新增“实名状态”,提供“全部”“已实名”“未实名”选项。
|
- 卡列表和设备列表的筛选区新增“实名状态”,提供“全部”“已实名”“未实名”选项。
|
||||||
- 卡列表查询使用 `GET /api/admin/iot-cards`,设备列表查询使用 `GET /api/admin/devices`;选择状态后分别传递 `real_name_status=0|1`,未选择时不传该参数。
|
- 卡列表查询使用 `GET /api/admin/iot-cards/standalone`,设备列表查询使用 `GET /api/admin/devices`;选择状态后分别传递 `real_name_status=0|1`,未选择时不传该参数。
|
||||||
- 卡和设备列表项的类型契约支持 `real_name_status: int` 与 `real_name_status_name: string`。
|
- 卡和设备列表项的类型契约支持 `real_name_status: int` 与 `real_name_status_name: string`。
|
||||||
- 两个列表表格新增“实名状态”列,直接展示接口返回的 `real_name_status_name`。
|
- 两个列表表格新增“实名状态”列,直接展示接口返回的 `real_name_status_name`。
|
||||||
- 设备列表直接使用设备列表接口的实名状态字段,不遍历或关联绑定卡计算设备实名状态。
|
- 设备列表直接使用设备列表接口的实名状态字段,不遍历或关联绑定卡计算设备实名状态。
|
||||||
@@ -26,7 +26,7 @@
|
|||||||
- `src/views/asset-management/iot-card-management/index.vue`
|
- `src/views/asset-management/iot-card-management/index.vue`
|
||||||
- `src/views/asset-management/device-list/index.vue`
|
- `src/views/asset-management/device-list/index.vue`
|
||||||
- API contracts:
|
- API contracts:
|
||||||
- `GET /api/admin/iot-cards?real_name_status=0|1`
|
- `GET /api/admin/iot-cards/standalone?real_name_status=0|1`
|
||||||
- `GET /api/admin/devices?real_name_status=0|1`
|
- `GET /api/admin/devices?real_name_status=0|1`
|
||||||
- List items return `real_name_status: int` and `real_name_status_name: string`
|
- List items return `real_name_status: int` and `real_name_status_name: string`
|
||||||
- Dependencies:
|
- Dependencies:
|
||||||
|
|||||||
@@ -2,19 +2,19 @@
|
|||||||
|
|
||||||
### Requirement: IoT Card Realname Status Query Contract
|
### Requirement: IoT Card Realname Status Query Contract
|
||||||
|
|
||||||
The IoT card management list integration SHALL query `GET /api/admin/iot-cards` and support an optional numeric `real_name_status` parameter. The list-item contract SHALL include `real_name_status` and `real_name_status_name`.
|
The IoT card management list integration SHALL query `GET /api/admin/iot-cards/standalone` and support an optional numeric `real_name_status` parameter. The list-item contract SHALL include `real_name_status` and `real_name_status_name`.
|
||||||
|
|
||||||
#### Scenario: Query cards by realname status
|
#### Scenario: Query cards by realname status
|
||||||
|
|
||||||
- **GIVEN** 用户正在后台卡列表使用实名状态筛选
|
- **GIVEN** 用户正在后台卡列表使用实名状态筛选
|
||||||
- **WHEN** 用户选择“已实名”并执行搜索
|
- **WHEN** 用户选择“已实名”并执行搜索
|
||||||
- **THEN** 系统 MUST call `GET /api/admin/iot-cards` with `real_name_status=1`
|
- **THEN** 系统 MUST call `GET /api/admin/iot-cards/standalone` with `real_name_status=1`
|
||||||
|
|
||||||
#### Scenario: Query unverified cards
|
#### Scenario: Query unverified cards
|
||||||
|
|
||||||
- **GIVEN** 用户正在后台卡列表使用实名状态筛选
|
- **GIVEN** 用户正在后台卡列表使用实名状态筛选
|
||||||
- **WHEN** 用户选择“未实名”并执行搜索
|
- **WHEN** 用户选择“未实名”并执行搜索
|
||||||
- **THEN** 系统 MUST call `GET /api/admin/iot-cards` with `real_name_status=0`
|
- **THEN** 系统 MUST call `GET /api/admin/iot-cards/standalone` with `real_name_status=0`
|
||||||
- **AND** 前端 MUST NOT 因为该值为 `0` 而省略此参数
|
- **AND** 前端 MUST NOT 因为该值为 `0` 而省略此参数
|
||||||
|
|
||||||
#### Scenario: Query all cards without status restriction
|
#### Scenario: Query all cards without status restriction
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
- [ ] 1.1 扩展卡列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`。
|
- [ ] 1.1 扩展卡列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`。
|
||||||
- [ ] 1.2 扩展设备列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`。
|
- [ ] 1.2 扩展设备列表查询参数和列表项类型,支持可选 `real_name_status` 以及必需的 `real_name_status_name`。
|
||||||
- [ ] 1.3 将卡列表查询接入 `GET /api/admin/iot-cards` 并传递实名状态筛选参数。
|
- [ ] 1.3 将卡列表查询接入 `GET /api/admin/iot-cards/standalone` 并传递实名状态筛选参数。
|
||||||
|
|
||||||
## 2. Card List
|
## 2. Card List
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
## Context
|
||||||
|
|
||||||
|
三个后台业务列表都需要展示相同的审批摘要,但各自保留既有退款、充值或换货操作。审批来源和业务处理状态均由后端列表接口返回,前端不请求单条审批详情来填充表格。
|
||||||
|
|
||||||
|
## Goals / Non-Goals
|
||||||
|
|
||||||
|
- Goals:
|
||||||
|
- 统一展示提交人、审批状态、当前审批人摘要和业务处理状态。
|
||||||
|
- 正确区分无审批、历史本地审批和企微审批。
|
||||||
|
- 在不增加逐行请求的前提下支持长摘要完整查看。
|
||||||
|
- Non-Goals:
|
||||||
|
- 不创建、修改或撤回审批流程。
|
||||||
|
- 不增加历史本地审批操作按钮。
|
||||||
|
- 不以 `approval_status` 推断 `processing_status`,或反向推断。
|
||||||
|
|
||||||
|
## Decisions
|
||||||
|
|
||||||
|
- Decision: 三个列表项模型复用相同名称和语义的审批摘要字段,字段由各自的列表接口直接返回。
|
||||||
|
- Decision: `approval_source=none` 时审批状态与当前审批人摘要均显示 `-`;`legacy` 时审批状态固定显示“历史审批”,当前审批人摘要显示 `-`;`wecom` 时直接展示 `approval_status_name` 和 `current_approver_summary`。
|
||||||
|
- Decision: 审批人摘要仅负责展示,使用表格溢出省略与 tooltip 呈现完整文本。
|
||||||
|
- Decision: 业务处理状态单独读取 `processing_status_name`,不与审批状态混合或映射。
|
||||||
|
- Decision: 列表分页和刷新仅调用现有列表 API,禁止为每条记录请求审批详情。
|
||||||
|
- Alternatives considered: 从单条详情或企微审批 API 批量补齐摘要。未采用,因为会引入 N+1 请求并与列表响应已提供的摘要字段重复。
|
||||||
|
|
||||||
|
## Risks / Trade-offs
|
||||||
|
|
||||||
|
- 后端遗漏摘要字段时信息不可用 -> 统一显示稳定占位,不影响原有列表和业务操作。
|
||||||
|
- 审批状态名称可能为空 -> 企微来源显示稳定占位,不自行翻译状态码。
|
||||||
|
- 审批人摘要长度不受控 -> 表格列使用溢出省略和 hover 完整文本。
|
||||||
|
|
||||||
|
## Migration Plan
|
||||||
|
|
||||||
|
1. 扩展三个列表项类型以保留审批摘要字段。
|
||||||
|
2. 在三个列表中添加四个展示列并遵循审批来源规则。
|
||||||
|
3. 验证 `none`、`legacy`、`wecom` 和处理状态为空的响应。
|
||||||
|
4. 验证刷新、分页未出现逐行审批详情请求。
|
||||||
|
5. 如需回滚,移除列表列与附加类型字段;不涉及数据迁移。
|
||||||
|
|
||||||
|
## Open Questions
|
||||||
|
|
||||||
|
- 无。
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
# Change: 新增业务列表提交人与审批摘要
|
||||||
|
|
||||||
|
## Why
|
||||||
|
|
||||||
|
退款、代理充值和换货列表当前无法直接显示提交人、企微审批进度及业务处理进度。运营人员需要进入详情或依赖额外沟通才能判断记录由谁发起、审批进行到哪一步以及后续业务是否完成。
|
||||||
|
|
||||||
|
## What Changes
|
||||||
|
|
||||||
|
- 在退款列表、代理充值列表和换货列表增加“提交人”“审批状态”“当前审批人摘要”“业务处理状态”四列。
|
||||||
|
- 三个列表接口项统一支持 `submitter_name`、`approval_source`、`approval_status`、`approval_status_name`、`current_approver_summary`、`processing_status`、`processing_status_name`。
|
||||||
|
- `approval_source=none` 时审批状态和当前审批人摘要显示 `-`。
|
||||||
|
- `approval_source=legacy` 时审批状态显示“历史审批”,作为只读历史信息,不新增审批操作按钮。
|
||||||
|
- `approval_source=wecom` 时显示后端返回的企微审批状态及当前审批人摘要;超长审批人摘要使用省略显示并在悬浮时展示完整文本。
|
||||||
|
- 业务处理状态直接展示后端 `processing_status_name`,与审批状态分列展示。
|
||||||
|
- 列表仅使用列表响应中的审批摘要字段,翻页和刷新时不得为每行额外请求审批详情。
|
||||||
|
|
||||||
|
## Impact
|
||||||
|
|
||||||
|
- Affected specs:
|
||||||
|
- `order-management`
|
||||||
|
- `agent-recharge`
|
||||||
|
- `exchange-management`
|
||||||
|
- Affected code:
|
||||||
|
- `src/types/api/refund.ts`
|
||||||
|
- `src/types/api/agentRecharge.ts`
|
||||||
|
- `src/api/modules/exchange.ts`
|
||||||
|
- `src/views/finance/refund/index.vue`
|
||||||
|
- `src/views/finance/agent-recharge/index.vue`
|
||||||
|
- `src/views/asset-management/exchange-management/index.vue`
|
||||||
|
- API contracts:
|
||||||
|
- `GET /api/admin/refunds`
|
||||||
|
- `GET /api/admin/agent-recharges`
|
||||||
|
- `GET /api/admin/exchanges`
|
||||||
|
- Out of scope:
|
||||||
|
- 审批发起、撤回、审批操作或企微审批详情页。
|
||||||
|
- 前端根据业务状态或审批步骤推导审批结果和业务处理状态。
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: Agent Recharge List Approval Summary Contract
|
||||||
|
|
||||||
|
The `GET /api/admin/agent-recharges` list-item contract SHALL support `submitter_name`, `approval_source`, `approval_status`, `approval_status_name`, `current_approver_summary`, `processing_status`, and `processing_status_name`.
|
||||||
|
|
||||||
|
#### Scenario: Receive agent recharge approval summary fields
|
||||||
|
|
||||||
|
- **GIVEN** 后台代理充值列表接口返回充值记录
|
||||||
|
- **WHEN** 前端解析列表响应
|
||||||
|
- **THEN** 代理充值列表项类型 MUST preserve all approval and processing summary fields
|
||||||
|
- **AND** 页面 MUST NOT request an individual approval-detail API to populate the row
|
||||||
|
|
||||||
|
### Requirement: Agent Recharge List Approval And Processing Display
|
||||||
|
|
||||||
|
The agent recharge list SHALL display `提交人`, `审批状态`, `当前审批人摘要`, and `业务处理状态` as distinct columns based on backend summary fields.
|
||||||
|
|
||||||
|
#### Scenario: Display recharge with no approval source
|
||||||
|
|
||||||
|
- **GIVEN** 代理充值记录的 `approval_source=none`
|
||||||
|
- **WHEN** 页面渲染代理充值列表行
|
||||||
|
- **THEN** `审批状态` MUST display `-`
|
||||||
|
- **AND** `当前审批人摘要` MUST display `-`
|
||||||
|
|
||||||
|
#### Scenario: Display legacy recharge approval read-only
|
||||||
|
|
||||||
|
- **GIVEN** 代理充值记录的 `approval_source=legacy`
|
||||||
|
- **WHEN** 页面渲染代理充值列表行
|
||||||
|
- **THEN** `审批状态` MUST display `历史审批`
|
||||||
|
- **AND** 页面 MUST NOT add an approval operation button for that historical approval
|
||||||
|
|
||||||
|
#### Scenario: Display WeCom recharge approval summary
|
||||||
|
|
||||||
|
- **GIVEN** 代理充值记录的 `approval_source=wecom`
|
||||||
|
- **WHEN** 页面渲染代理充值列表行
|
||||||
|
- **THEN** `审批状态` MUST display backend `approval_status_name`
|
||||||
|
- **AND** `当前审批人摘要` MUST display backend `current_approver_summary`
|
||||||
|
- **AND** `业务处理状态` MUST independently display backend `processing_status_name`
|
||||||
|
|
||||||
|
#### Scenario: View long recharge approver summary
|
||||||
|
|
||||||
|
- **GIVEN** 代理充值记录的 `current_approver_summary` exceeds its table cell width
|
||||||
|
- **WHEN** 页面渲染当前审批人摘要列
|
||||||
|
- **THEN** 摘要 MUST be visually truncated in the cell
|
||||||
|
- **AND** 用户 MUST be able to view the complete backend text on hover
|
||||||
|
|
||||||
|
#### Scenario: Paginate recharges without per-row approval requests
|
||||||
|
|
||||||
|
- **WHEN** 用户切换代理充值列表页码或刷新列表
|
||||||
|
- **THEN** 页面 MUST use the agent recharge list API response for approval summaries
|
||||||
|
- **AND** 页面 MUST NOT issue approval-detail requests per recharge row
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: Exchange List Approval Summary Contract
|
||||||
|
|
||||||
|
The `GET /api/admin/exchanges` list-item contract SHALL support `submitter_name`, `approval_source`, `approval_status`, `approval_status_name`, `current_approver_summary`, `processing_status`, and `processing_status_name`.
|
||||||
|
|
||||||
|
#### Scenario: Receive exchange approval summary fields
|
||||||
|
|
||||||
|
- **GIVEN** 后台换货列表接口返回换货记录
|
||||||
|
- **WHEN** 前端解析列表响应
|
||||||
|
- **THEN** 换货列表项类型 MUST preserve all approval and processing summary fields
|
||||||
|
- **AND** 页面 MUST NOT request an individual approval-detail API to populate the row
|
||||||
|
|
||||||
|
### Requirement: Exchange List Approval And Processing Display
|
||||||
|
|
||||||
|
The exchange management list SHALL display `提交人`, `审批状态`, `当前审批人摘要`, and `业务处理状态` as distinct columns based on backend summary fields.
|
||||||
|
|
||||||
|
#### Scenario: Display exchange with no approval source
|
||||||
|
|
||||||
|
- **GIVEN** 换货记录的 `approval_source=none`
|
||||||
|
- **WHEN** 页面渲染换货列表行
|
||||||
|
- **THEN** `审批状态` MUST display `-`
|
||||||
|
- **AND** `当前审批人摘要` MUST display `-`
|
||||||
|
|
||||||
|
#### Scenario: Display legacy exchange approval read-only
|
||||||
|
|
||||||
|
- **GIVEN** 换货记录的 `approval_source=legacy`
|
||||||
|
- **WHEN** 页面渲染换货列表行
|
||||||
|
- **THEN** `审批状态` MUST display `历史审批`
|
||||||
|
- **AND** 页面 MUST NOT add an approval operation button for that historical approval
|
||||||
|
|
||||||
|
#### Scenario: Display WeCom exchange approval summary
|
||||||
|
|
||||||
|
- **GIVEN** 换货记录的 `approval_source=wecom`
|
||||||
|
- **WHEN** 页面渲染换货列表行
|
||||||
|
- **THEN** `审批状态` MUST display backend `approval_status_name`
|
||||||
|
- **AND** `当前审批人摘要` MUST display backend `current_approver_summary`
|
||||||
|
- **AND** `业务处理状态` MUST independently display backend `processing_status_name`
|
||||||
|
|
||||||
|
#### Scenario: View long exchange approver summary
|
||||||
|
|
||||||
|
- **GIVEN** 换货记录的 `current_approver_summary` exceeds its table cell width
|
||||||
|
- **WHEN** 页面渲染当前审批人摘要列
|
||||||
|
- **THEN** 摘要 MUST be visually truncated in the cell
|
||||||
|
- **AND** 用户 MUST be able to view the complete backend text on hover
|
||||||
|
|
||||||
|
#### Scenario: Paginate exchanges without per-row approval requests
|
||||||
|
|
||||||
|
- **WHEN** 用户切换换货列表页码或刷新列表
|
||||||
|
- **THEN** 页面 MUST use the exchange list API response for approval summaries
|
||||||
|
- **AND** 页面 MUST NOT issue approval-detail requests per exchange row
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
## ADDED Requirements
|
||||||
|
|
||||||
|
### Requirement: Refund List Approval Summary Contract
|
||||||
|
|
||||||
|
The `GET /api/admin/refunds` list-item contract SHALL support `submitter_name`, `approval_source`, `approval_status`, `approval_status_name`, `current_approver_summary`, `processing_status`, and `processing_status_name`.
|
||||||
|
|
||||||
|
#### Scenario: Receive refund approval summary fields
|
||||||
|
|
||||||
|
- **GIVEN** 后台退款列表接口返回退款记录
|
||||||
|
- **WHEN** 前端解析列表响应
|
||||||
|
- **THEN** 退款列表项类型 MUST preserve all approval and processing summary fields
|
||||||
|
- **AND** 页面 MUST NOT request an individual approval-detail API to populate the row
|
||||||
|
|
||||||
|
### Requirement: Refund List Approval And Processing Display
|
||||||
|
|
||||||
|
The refund management list SHALL display `提交人`, `审批状态`, `当前审批人摘要`, and `业务处理状态` as distinct columns based on backend summary fields.
|
||||||
|
|
||||||
|
#### Scenario: Display refund with no approval source
|
||||||
|
|
||||||
|
- **GIVEN** 退款记录的 `approval_source=none`
|
||||||
|
- **WHEN** 页面渲染退款列表行
|
||||||
|
- **THEN** `审批状态` MUST display `-`
|
||||||
|
- **AND** `当前审批人摘要` MUST display `-`
|
||||||
|
|
||||||
|
#### Scenario: Display legacy refund approval read-only
|
||||||
|
|
||||||
|
- **GIVEN** 退款记录的 `approval_source=legacy`
|
||||||
|
- **WHEN** 页面渲染退款列表行
|
||||||
|
- **THEN** `审批状态` MUST display `历史审批`
|
||||||
|
- **AND** 页面 MUST NOT add an approval operation button for that historical approval
|
||||||
|
|
||||||
|
#### Scenario: Display WeCom refund approval summary
|
||||||
|
|
||||||
|
- **GIVEN** 退款记录的 `approval_source=wecom`
|
||||||
|
- **WHEN** 页面渲染退款列表行
|
||||||
|
- **THEN** `审批状态` MUST display backend `approval_status_name`
|
||||||
|
- **AND** `当前审批人摘要` MUST display backend `current_approver_summary`
|
||||||
|
- **AND** `业务处理状态` MUST independently display backend `processing_status_name`
|
||||||
|
|
||||||
|
#### Scenario: View long refund approver summary
|
||||||
|
|
||||||
|
- **GIVEN** 退款记录的 `current_approver_summary` exceeds its table cell width
|
||||||
|
- **WHEN** 页面渲染当前审批人摘要列
|
||||||
|
- **THEN** 摘要 MUST be visually truncated in the cell
|
||||||
|
- **AND** 用户 MUST be able to view the complete backend text on hover
|
||||||
|
|
||||||
|
#### Scenario: Paginate refunds without per-row approval requests
|
||||||
|
|
||||||
|
- **WHEN** 用户切换退款列表页码或刷新列表
|
||||||
|
- **THEN** 页面 MUST use the refund list API response for approval summaries
|
||||||
|
- **AND** 页面 MUST NOT issue approval-detail requests per refund row
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
## 1. List Contracts
|
||||||
|
|
||||||
|
- [x] 1.1 扩展退款、代理充值和换货列表项类型,支持 `submitter_name`、`approval_source`、`approval_status`、`approval_status_name`、`current_approver_summary`、`processing_status`、`processing_status_name`。
|
||||||
|
- [x] 1.2 确认三个列表 API 使用列表响应直接提供上述字段,不新增逐条审批详情查询。
|
||||||
|
|
||||||
|
## 2. Shared Summary Behavior
|
||||||
|
|
||||||
|
- [x] 2.1 实现审批来源展示规则:`none` 显示 `-`,`legacy` 显示“历史审批”且只读,`wecom` 显示后端审批状态名称。
|
||||||
|
- [x] 2.2 将当前审批人摘要限制为单行省略,并提供完整文本悬浮提示。
|
||||||
|
- [x] 2.3 将业务处理状态独立显示为后端 `processing_status_name`,缺失时显示稳定占位内容。
|
||||||
|
|
||||||
|
## 3. Refund List
|
||||||
|
|
||||||
|
- [x] 3.1 在退款列表增加提交人、审批状态、当前审批人摘要、业务处理状态列。
|
||||||
|
- [x] 3.2 保留退款既有审批与业务操作,不为历史审批记录增加新操作按钮。
|
||||||
|
|
||||||
|
## 4. Agent Recharge List
|
||||||
|
|
||||||
|
- [x] 4.1 在代理充值列表增加提交人、审批状态、当前审批人摘要、业务处理状态列。
|
||||||
|
- [x] 4.2 保留代理充值既有确认支付、拒绝等操作,不为历史审批记录增加新操作按钮。
|
||||||
|
|
||||||
|
## 5. Exchange List
|
||||||
|
|
||||||
|
- [x] 5.1 在换货列表增加提交人、审批状态、当前审批人摘要、业务处理状态列。
|
||||||
|
- [x] 5.2 保留换货既有流程和资产筛选逻辑,不为历史审批记录增加新操作按钮。
|
||||||
|
|
||||||
|
## 6. Verification
|
||||||
|
|
||||||
|
- [x] 6.1 验证三类列表在 `approval_source=none` 时审批状态和当前审批人摘要均显示 `-`。
|
||||||
|
- [x] 6.2 验证 `approval_source=legacy` 时显示“历史审批”且没有新增审批操作,`wecom` 时显示后端审批状态和当前审批人摘要。
|
||||||
|
- [x] 6.3 验证长当前审批人摘要会省略显示并能通过悬浮查看完整文本。
|
||||||
|
- [x] 6.4 验证三个列表的业务处理状态独立显示,分页和刷新不触发逐行审批详情请求。
|
||||||
|
- [x] 6.5 运行相关类型检查、lint 或构建验证。
|
||||||
@@ -349,16 +349,6 @@ export class CardService extends BaseService {
|
|||||||
return this.getPage<StandaloneIotCard>('/api/admin/iot-cards/standalone', params)
|
return this.getPage<StandaloneIotCard>('/api/admin/iot-cards/standalone', params)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 获取 IoT 卡列表
|
|
||||||
* @param params 查询参数
|
|
||||||
*/
|
|
||||||
static getIotCards(
|
|
||||||
params?: StandaloneCardQueryParams
|
|
||||||
): Promise<PaginationResponse<StandaloneIotCard>> {
|
|
||||||
return this.getPage<StandaloneIotCard>('/api/admin/iot-cards', params)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 批量分配单卡
|
* 批量分配单卡
|
||||||
* @param data 分配参数
|
* @param data 分配参数
|
||||||
|
|||||||
@@ -53,6 +53,13 @@ export interface ExchangeResponse {
|
|||||||
express_no?: string
|
express_no?: string
|
||||||
inherited_shop_id?: number | null
|
inherited_shop_id?: number | null
|
||||||
inherited_shop_name?: string | null
|
inherited_shop_name?: string | null
|
||||||
|
submitter_name?: string | null // 提交人名称
|
||||||
|
approval_source?: 'none' | 'legacy' | 'wecom' | null // 审批来源
|
||||||
|
approval_status?: string | null // 审批状态
|
||||||
|
approval_status_name?: string | null // 审批状态名称
|
||||||
|
current_approver_summary?: string | null // 当前审批人摘要
|
||||||
|
processing_status?: string | null // 业务处理状态
|
||||||
|
processing_status_name?: string | null // 业务处理状态名称
|
||||||
remark?: string
|
remark?: string
|
||||||
created_at: string
|
created_at: string
|
||||||
updated_at: string
|
updated_at: string
|
||||||
|
|||||||
@@ -34,6 +34,13 @@ export interface AgentRecharge {
|
|||||||
payment_voucher_key?: string[] | string // 凭证附件列表;历史数据可能为单字符串或逗号字符串
|
payment_voucher_key?: string[] | string // 凭证附件列表;历史数据可能为单字符串或逗号字符串
|
||||||
rejection_reason?: string | null // 拒绝原因
|
rejection_reason?: string | null // 拒绝原因
|
||||||
remark?: string // 运营备注
|
remark?: string // 运营备注
|
||||||
|
submitter_name?: string | null // 提交人名称
|
||||||
|
approval_source?: 'none' | 'legacy' | 'wecom' | null // 审批来源
|
||||||
|
approval_status?: string | null // 审批状态
|
||||||
|
approval_status_name?: string | null // 审批状态名称
|
||||||
|
current_approver_summary?: string | null // 当前审批人摘要
|
||||||
|
processing_status?: string | null // 业务处理状态
|
||||||
|
processing_status_name?: string | null // 业务处理状态名称
|
||||||
created_at: string
|
created_at: string
|
||||||
paid_at: string | null
|
paid_at: string | null
|
||||||
completed_at: string | null
|
completed_at: string | null
|
||||||
|
|||||||
@@ -31,6 +31,13 @@ export interface Refund {
|
|||||||
remark: string
|
remark: string
|
||||||
asset_reset: boolean
|
asset_reset: boolean
|
||||||
commission_deducted: boolean
|
commission_deducted: boolean
|
||||||
|
submitter_name?: string | null // 提交人名称
|
||||||
|
approval_source?: 'none' | 'legacy' | 'wecom' | null // 审批来源
|
||||||
|
approval_status?: string | null // 审批状态
|
||||||
|
approval_status_name?: string | null // 审批状态名称
|
||||||
|
current_approver_summary?: string | null // 当前审批人摘要
|
||||||
|
processing_status?: string | null // 业务处理状态
|
||||||
|
processing_status_name?: string | null // 业务处理状态名称
|
||||||
creator: number
|
creator: number
|
||||||
processor_id: number | null
|
processor_id: number | null
|
||||||
processed_at: string | null
|
processed_at: string | null
|
||||||
|
|||||||
22
src/utils/business/approvalSummary.ts
Normal file
22
src/utils/business/approvalSummary.ts
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
export type ApprovalSource = 'none' | 'legacy' | 'wecom'
|
||||||
|
|
||||||
|
export interface ApprovalSummary {
|
||||||
|
approval_source?: ApprovalSource | null
|
||||||
|
approval_status_name?: string | null
|
||||||
|
current_approver_summary?: string | null
|
||||||
|
processing_status_name?: string | null
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getApprovalStatusText = (summary: ApprovalSummary): string => {
|
||||||
|
if (summary.approval_source === 'legacy') return '历史审批'
|
||||||
|
if (summary.approval_source === 'wecom') return summary.approval_status_name || '-'
|
||||||
|
return '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getCurrentApproverSummaryText = (summary: ApprovalSummary): string => {
|
||||||
|
if (summary.approval_source !== 'wecom') return '-'
|
||||||
|
return summary.current_approver_summary || '-'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const getProcessingStatusText = (summary: ApprovalSummary): string =>
|
||||||
|
summary.processing_status_name || '-'
|
||||||
@@ -7,4 +7,5 @@ export * from './validate'
|
|||||||
export * from './calculate'
|
export * from './calculate'
|
||||||
export * from './voucher'
|
export * from './voucher'
|
||||||
export * from './apiRateLimit'
|
export * from './apiRateLimit'
|
||||||
|
export * from './approvalSummary'
|
||||||
export * from './expiryEstimate'
|
export * from './expiryEstimate'
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<ArtSearchBar
|
<ArtSearchBar
|
||||||
v-model:filter="searchForm"
|
v-model:filter="searchForm"
|
||||||
:items="searchFormItems"
|
:items="searchFormItems"
|
||||||
:show-expand="false"
|
:show-expand="true"
|
||||||
label-width="90"
|
label-width="90"
|
||||||
@reset="handleReset"
|
@reset="handleReset"
|
||||||
@search="handleSearch"
|
@search="handleSearch"
|
||||||
@@ -390,6 +390,11 @@
|
|||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
|
import {
|
||||||
|
getApprovalStatusText,
|
||||||
|
getCurrentApproverSummaryText,
|
||||||
|
getProcessingStatusText
|
||||||
|
} from '@/utils/business/approvalSummary'
|
||||||
import { RoutesAlias } from '@/router/routesAlias'
|
import { RoutesAlias } from '@/router/routesAlias'
|
||||||
|
|
||||||
defineOptions({ name: 'ExchangeManagement' })
|
defineOptions({ name: 'ExchangeManagement' })
|
||||||
@@ -712,6 +717,33 @@
|
|||||||
width: 220,
|
width: 220,
|
||||||
formatter: (row: ExchangeResponse) => row.new_asset_identifier || '--'
|
formatter: (row: ExchangeResponse) => row.new_asset_identifier || '--'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
prop: 'submitter_name',
|
||||||
|
label: '提交人',
|
||||||
|
width: 120,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: ExchangeResponse) => row.submitter_name || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'approval_status',
|
||||||
|
label: '审批状态',
|
||||||
|
width: 120,
|
||||||
|
formatter: (row: ExchangeResponse) => getApprovalStatusText(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'current_approver_summary',
|
||||||
|
label: '当前审批人摘要',
|
||||||
|
minWidth: 180,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: ExchangeResponse) => getCurrentApproverSummaryText(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'processing_status_name',
|
||||||
|
label: '业务处理状态',
|
||||||
|
width: 140,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: ExchangeResponse) => getProcessingStatusText(row)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
prop: 'recipient_name',
|
prop: 'recipient_name',
|
||||||
label: '收货人姓名',
|
label: '收货人姓名',
|
||||||
|
|||||||
@@ -2365,7 +2365,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const res = await CardService.getIotCards(params)
|
const res = await CardService.getStandaloneIotCards(params)
|
||||||
if (res.code === 0) {
|
if (res.code === 0) {
|
||||||
cardList.value = res.data.items || []
|
cardList.value = res.data.items || []
|
||||||
pagination.total = res.data.total || 0
|
pagination.total = res.data.total || 0
|
||||||
|
|||||||
@@ -236,6 +236,11 @@
|
|||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { formatDateTime } from '@/utils/business/format'
|
import { formatDateTime } from '@/utils/business/format'
|
||||||
|
import {
|
||||||
|
getApprovalStatusText,
|
||||||
|
getCurrentApproverSummaryText,
|
||||||
|
getProcessingStatusText
|
||||||
|
} from '@/utils/business/approvalSummary'
|
||||||
import { hasVoucherKeys, toVoucherKeyList } from '@/utils/business'
|
import { hasVoucherKeys, toVoucherKeyList } from '@/utils/business'
|
||||||
import { useAuth } from '@/composables/useAuth'
|
import { useAuth } from '@/composables/useAuth'
|
||||||
import PaymentVoucherDialog from '@/components/business/PaymentVoucherDialog.vue'
|
import PaymentVoucherDialog from '@/components/business/PaymentVoucherDialog.vue'
|
||||||
@@ -365,6 +370,10 @@
|
|||||||
{ label: '店铺名称', prop: 'shop_name' },
|
{ label: '店铺名称', prop: 'shop_name' },
|
||||||
{ label: '充值金额', prop: 'amount' },
|
{ label: '充值金额', prop: 'amount' },
|
||||||
{ label: '状态', prop: 'status' },
|
{ label: '状态', prop: 'status' },
|
||||||
|
{ label: '提交人', prop: 'submitter_name' },
|
||||||
|
{ label: '审批状态', prop: 'approval_status' },
|
||||||
|
{ label: '当前审批人摘要', prop: 'current_approver_summary' },
|
||||||
|
{ label: '业务处理状态', prop: 'processing_status_name' },
|
||||||
{ label: '支付方式', prop: 'payment_method' },
|
{ label: '支付方式', prop: 'payment_method' },
|
||||||
{ label: '支付通道', prop: 'payment_channel' },
|
{ label: '支付通道', prop: 'payment_channel' },
|
||||||
{ label: '驳回原因', prop: 'rejection_reason' },
|
{ label: '驳回原因', prop: 'rejection_reason' },
|
||||||
@@ -524,6 +533,33 @@
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
prop: 'submitter_name',
|
||||||
|
label: '提交人',
|
||||||
|
width: 120,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: AgentRecharge) => row.submitter_name || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'approval_status',
|
||||||
|
label: '审批状态',
|
||||||
|
width: 120,
|
||||||
|
formatter: (row: AgentRecharge) => getApprovalStatusText(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'current_approver_summary',
|
||||||
|
label: '当前审批人摘要',
|
||||||
|
minWidth: 180,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: AgentRecharge) => getCurrentApproverSummaryText(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'processing_status_name',
|
||||||
|
label: '业务处理状态',
|
||||||
|
width: 140,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: AgentRecharge) => getProcessingStatusText(row)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
prop: 'payment_method',
|
prop: 'payment_method',
|
||||||
label: '支付方式',
|
label: '支付方式',
|
||||||
|
|||||||
@@ -267,6 +267,11 @@
|
|||||||
import type { SearchFormItem } from '@/types'
|
import type { SearchFormItem } from '@/types'
|
||||||
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
import { useCheckedColumns } from '@/composables/useCheckedColumns'
|
||||||
import { fenToYuan, formatDateTime, yuanToFen } from '@/utils/business/format'
|
import { fenToYuan, formatDateTime, yuanToFen } from '@/utils/business/format'
|
||||||
|
import {
|
||||||
|
getApprovalStatusText,
|
||||||
|
getCurrentApproverSummaryText,
|
||||||
|
getProcessingStatusText
|
||||||
|
} from '@/utils/business/approvalSummary'
|
||||||
import { hasVoucherKeys, toVoucherKeyList } from '@/utils/business'
|
import { hasVoucherKeys, toVoucherKeyList } from '@/utils/business'
|
||||||
import { RoutesAlias } from '@/router/routesAlias'
|
import { RoutesAlias } from '@/router/routesAlias'
|
||||||
import PaymentVoucherDialog from '@/components/business/PaymentVoucherDialog.vue'
|
import PaymentVoucherDialog from '@/components/business/PaymentVoucherDialog.vue'
|
||||||
@@ -391,6 +396,10 @@
|
|||||||
{ label: '实际退款金额', prop: 'approved_refund_amount' },
|
{ label: '实际退款金额', prop: 'approved_refund_amount' },
|
||||||
{ label: '实收金额', prop: 'actual_received_amount' },
|
{ label: '实收金额', prop: 'actual_received_amount' },
|
||||||
{ label: '状态', prop: 'status' },
|
{ label: '状态', prop: 'status' },
|
||||||
|
{ label: '提交人', prop: 'submitter_name' },
|
||||||
|
{ label: '审批状态', prop: 'approval_status' },
|
||||||
|
{ label: '当前审批人摘要', prop: 'current_approver_summary' },
|
||||||
|
{ label: '业务处理状态', prop: 'processing_status_name' },
|
||||||
{ label: '退款原因', prop: 'refund_reason' },
|
{ label: '退款原因', prop: 'refund_reason' },
|
||||||
{ label: '拒绝原因', prop: 'reject_reason' },
|
{ label: '拒绝原因', prop: 'reject_reason' },
|
||||||
{ label: '审批备注', prop: 'remark' },
|
{ label: '审批备注', prop: 'remark' },
|
||||||
@@ -547,6 +556,33 @@
|
|||||||
return h(ElTag, { type: getStatusType(row.status) }, () => getStatusText(row.status))
|
return h(ElTag, { type: getStatusType(row.status) }, () => getStatusText(row.status))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
prop: 'submitter_name',
|
||||||
|
label: '提交人',
|
||||||
|
width: 120,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: Refund) => row.submitter_name || '-'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'approval_status',
|
||||||
|
label: '审批状态',
|
||||||
|
width: 120,
|
||||||
|
formatter: (row: Refund) => getApprovalStatusText(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'current_approver_summary',
|
||||||
|
label: '当前审批人摘要',
|
||||||
|
minWidth: 180,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: Refund) => getCurrentApproverSummaryText(row)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
prop: 'processing_status_name',
|
||||||
|
label: '业务处理状态',
|
||||||
|
width: 140,
|
||||||
|
showOverflowTooltip: true,
|
||||||
|
formatter: (row: Refund) => getProcessingStatusText(row)
|
||||||
|
},
|
||||||
{
|
{
|
||||||
prop: 'refund_reason',
|
prop: 'refund_reason',
|
||||||
label: '退款原因',
|
label: '退款原因',
|
||||||
|
|||||||
Reference in New Issue
Block a user