fix: update some files
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 5m44s
All checks were successful
构建并部署前端到测试环境 / build-and-deploy (push) Successful in 5m44s
This commit is contained in:
50
openspec/changes/add-historical-approval-resend/design.md
Normal file
50
openspec/changes/add-historical-approval-resend/design.md
Normal file
@@ -0,0 +1,50 @@
|
||||
## Context
|
||||
|
||||
退款和代理充值已经接入企微审批,但部分历史记录在审批流程上线前创建,列表中的 `approval_status` 为空。这些记录需要由运营人员手动触发一次审批补发,才能进入企微审批链路。
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
- Goals: 提供代理充值和退款的历史审批补发入口。
|
||||
- Goals: 通过路径参数指定目标记录,并复用后端返回的完整记录与审批状态。
|
||||
- Goals: 由明确的状态规则控制入口展示,后端做最终资格校验。
|
||||
- Non-Goals: 不在前端实现审批提交、审批回调或审批引擎。
|
||||
- Non-Goals: 不修改历史记录的业务字段、金额或支付/退款结果。
|
||||
- Non-Goals: 不提供批量自动补发。
|
||||
|
||||
## Decisions
|
||||
|
||||
- Decision: 两个模块分别新增 `triggerApproval(id)` 服务方法,返回完整业务记录并保留审批字段。
|
||||
- Rationale: 两个接口契约一致,成功后页面需要立即展示最新审批状态,完整记录可直接用于刷新。
|
||||
|
||||
- Decision: 代理充值仅在 `approval_status` 为空且 `status` 不属于已完成、已驳回、已关闭时显示补发入口;退款仅在 `status=待审批` 且 `approval_status` 为空时显示补发入口。
|
||||
- Rationale: 与业务规则一致,避免对已进入审批或已终结的记录重复补发;后端仍做最终资格校验。
|
||||
|
||||
- Decision: 引入独立按钮权限 `agent_recharge:trigger_approval` 和 `refund:trigger_approval`。
|
||||
- Rationale: 补发审批是财务相关敏感操作,需与现有确认支付、拒绝、重新申请权限区分。
|
||||
|
||||
- Decision: 补发审批与现有“确认支付/拒绝”和“重新申请”操作共存。
|
||||
- Rationale: 它们承担不同职责;补发审批只是把历史记录推进企微审批,不改变后续人工确认或重新申请的流程。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- Risk: 代理充值中 `status=已支付`、`已退款` 等非终态记录是否允许补发,需要后端最终确认。
|
||||
- Mitigation: 前端按约定的审批状态与状态排除规则展示入口,后端对不允许的记录返回错误并稳定展示。
|
||||
|
||||
- Risk: 接口可能对部分状态返回拒绝。
|
||||
- Mitigation: 前端处理后端错误信息,不将失败记录标记为已补发。
|
||||
|
||||
- Risk: 重复点击可能触发多次审批提交。
|
||||
- Mitigation: 提交期间锁定按钮并禁用重复触发;后端应保证幂等或返回明确的已存在审批提示。
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. 确认两个 `trigger-approval` 接口的响应字段与现有 `AgentRecharge`、`Refund` 类型一致。
|
||||
2. 新增服务方法和按钮权限。
|
||||
3. 在列表接入补发审批入口及资格判断。
|
||||
4. 联调补发成功、接口拒绝、权限缺失、审批状态为空与状态不符合条件等场景。
|
||||
5. 验证与现有确认支付、拒绝、重新申请操作不冲突。
|
||||
|
||||
## Open Questions
|
||||
|
||||
- 后端对可补发记录的最终状态校验以及幂等性需确认。
|
||||
- 两个接口是否都需要独立权限码,还是复用现有审批/财务权限,需与后端权限配置对齐。
|
||||
39
openspec/changes/add-historical-approval-resend/proposal.md
Normal file
39
openspec/changes/add-historical-approval-resend/proposal.md
Normal file
@@ -0,0 +1,39 @@
|
||||
# Change: 补发历史线下代理充值审批与补发历史退款审批
|
||||
|
||||
## Why
|
||||
|
||||
历史线下代理充值记录和历史退款申请在企微审批流程上线前创建,列表中这些记录的审批状态为空,运营人员无法为它们补发审批流程。需要为这两类业务提供“补发审批”入口,调用后端触发审批接口,将历史记录纳入企微审批。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 在 `AgentRechargeService` 新增 `triggerApproval(id)`,调用 `POST /api/admin/agent-recharges/{id}/trigger-approval`。
|
||||
- 在 `RefundService` 新增 `triggerApproval(id)`,调用 `POST /api/admin/refunds/{id}/trigger-approval`。
|
||||
- 在代理充值列表为 `approval_status` 为空且 `status` 不属于已完成、已驳回、已关闭的充值记录增加“补发审批”操作。
|
||||
- 在退款列表为 `status=待审批` 且 `approval_status` 为空的退款申请增加“补发审批”操作。
|
||||
- 引入权限 `agent_recharge:trigger_approval` 和 `refund:trigger_approval`,仅对有权限的平台账号展示操作。
|
||||
- 补发成功后刷新列表并展示返回的最新审批状态;失败时展示后端错误信息。
|
||||
- 不改变现有“确认支付”“拒绝”“重新申请”等操作的资格和职责。
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs:
|
||||
- `agent-recharge`
|
||||
- `refund-management`
|
||||
- Affected code:
|
||||
- `src/api/modules/agentRecharge.ts`
|
||||
- `src/api/modules/refund.ts`
|
||||
- `src/types/api/agentRecharge.ts`
|
||||
- `src/types/api/refund.ts`
|
||||
- `src/views/finance/agent-recharge/agentRechargeActions.ts`
|
||||
- `src/views/finance/agent-recharge/index.vue`
|
||||
- `src/views/finance/refund/index.vue`
|
||||
- API contracts:
|
||||
- `POST /api/admin/agent-recharges/{id}/trigger-approval`
|
||||
- `POST /api/admin/refunds/{id}/trigger-approval`
|
||||
- Dependencies:
|
||||
- 后端按文档返回完整业务记录及当前审批状态。
|
||||
- 后端负责校验记录是否可补发审批,前端仅控制入口展示并处理后端拒绝。
|
||||
- Out of scope:
|
||||
- 企微审批的发起、撤回、通过、驳回或删除动作本身。
|
||||
- 修改历史记录的业务字段、金额或支付/退款结果。
|
||||
- 自动判断并批量补发历史审批。
|
||||
@@ -0,0 +1,56 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Agent Recharge Historical Approval Resend API
|
||||
|
||||
The agent recharge service SHALL expose a historical approval resend operation through `POST /api/admin/agent-recharges/{id}/trigger-approval`.
|
||||
|
||||
#### Scenario: Resend approval for a historical offline recharge
|
||||
|
||||
- **GIVEN** 一个需要补发审批的历史线下代理充值记录 `id`
|
||||
- **WHEN** 前端调用 `POST /api/admin/agent-recharges/{id}/trigger-approval`
|
||||
- **THEN** 请求 MUST 在路径参数中携带该充值记录 `id`
|
||||
- **AND** 成功响应 MUST 被解析为完整的 `AgentRecharge` 记录,并保留 `approval_provider`、`approval_instance_id`、`approval_status` 和 `approval_status_name` 字段
|
||||
|
||||
### Requirement: Agent Recharge Historical Approval Resend Entry
|
||||
|
||||
The agent recharge list page SHALL provide a `补发审批` action only for recharge records whose `approval_status` is empty and whose business `status` is not completed, rejected, or closed, and SHALL gate it by permission.
|
||||
|
||||
#### Scenario: Show resend action for an eligible recharge
|
||||
|
||||
- **GIVEN** 平台账号拥有 `agent_recharge:trigger_approval` 权限
|
||||
- **AND** 充值记录的 `approval_status` 为空(`null` 或 `undefined`)
|
||||
- **AND** 充值记录的 `status` 不属于已完成(3)、已驳回(6)、已关闭(4)
|
||||
- **WHEN** 页面渲染代理充值列表
|
||||
- **THEN** 页面 MUST 为该记录显示“补发审批”操作
|
||||
|
||||
#### Scenario: Hide resend action when approval status is present
|
||||
|
||||
- **GIVEN** 充值记录的 `approval_status` 不为空
|
||||
- **WHEN** 页面渲染该记录
|
||||
- **THEN** 页面 MUST NOT 显示“补发审批”操作
|
||||
|
||||
#### Scenario: Hide resend action for terminal recharge statuses
|
||||
|
||||
- **GIVEN** 充值记录的 `status` 为已完成(3)、已驳回(6)或已关闭(4)
|
||||
- **WHEN** 页面渲染该记录
|
||||
- **THEN** 页面 MUST NOT 显示“补发审批”操作
|
||||
|
||||
#### Scenario: Hide resend action without permission
|
||||
|
||||
- **GIVEN** 当前账号不拥有 `agent_recharge:trigger_approval` 权限
|
||||
- **WHEN** 页面渲染代理充值记录
|
||||
- **THEN** 页面 MUST NOT 显示“补发审批”操作
|
||||
|
||||
#### Scenario: Resend approval succeeds
|
||||
|
||||
- **GIVEN** 用户对符合条件的充值记录点击“补发审批”
|
||||
- **WHEN** 接口返回 `code=0`
|
||||
- **THEN** 页面 MUST 显示成功提示并刷新列表
|
||||
- **AND** 刷新后的记录 MUST 展示接口返回的最新审批状态
|
||||
|
||||
#### Scenario: Resend approval fails
|
||||
|
||||
- **GIVEN** 接口返回非零 `code` 或请求失败
|
||||
- **WHEN** 用户触发“补发审批”
|
||||
- **THEN** 页面 MUST 展示后端返回的错误信息
|
||||
- **AND** 页面 MUST NOT 将记录标记为已补发审批
|
||||
@@ -0,0 +1,56 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: Refund Historical Approval Resend API
|
||||
|
||||
The refund service SHALL expose a historical approval resend operation through `POST /api/admin/refunds/{id}/trigger-approval`.
|
||||
|
||||
#### Scenario: Resend approval for a historical refund
|
||||
|
||||
- **GIVEN** 一个需要补发审批的历史退款申请 `id`
|
||||
- **WHEN** 前端调用 `POST /api/admin/refunds/{id}/trigger-approval`
|
||||
- **THEN** 请求 MUST 在路径参数中携带该退款申请 `id`
|
||||
- **AND** 成功响应 MUST 被解析为完整的 `Refund` 记录,并保留 `approval_provider`、`approval_instance_id`、`approval_status` 和 `approval_status_name` 字段
|
||||
|
||||
### Requirement: Refund Historical Approval Resend Entry
|
||||
|
||||
The refund list page SHALL provide a `补发审批` action only for refund records whose `status` is pending approval and whose `approval_status` is empty, and SHALL gate it by permission.
|
||||
|
||||
#### Scenario: Show resend action for an eligible refund
|
||||
|
||||
- **GIVEN** 平台账号拥有 `refund:trigger_approval` 权限
|
||||
- **AND** 退款申请的 `status` 为待审批(1)
|
||||
- **AND** 退款申请的 `approval_status` 为空(`null` 或 `undefined`)
|
||||
- **WHEN** 页面渲染退款列表
|
||||
- **THEN** 页面 MUST 为该记录显示“补发审批”操作
|
||||
|
||||
#### Scenario: Hide resend action when refund status is not pending
|
||||
|
||||
- **GIVEN** 退款申请的 `status` 不为待审批(1)
|
||||
- **WHEN** 页面渲染该记录
|
||||
- **THEN** 页面 MUST NOT 显示“补发审批”操作
|
||||
|
||||
#### Scenario: Hide resend action when approval status is present
|
||||
|
||||
- **GIVEN** 退款申请的 `approval_status` 不为空
|
||||
- **WHEN** 页面渲染该记录
|
||||
- **THEN** 页面 MUST NOT 显示“补发审批”操作
|
||||
|
||||
#### Scenario: Hide resend action without permission
|
||||
|
||||
- **GIVEN** 当前账号不拥有 `refund:trigger_approval` 权限
|
||||
- **WHEN** 页面渲染退款记录
|
||||
- **THEN** 页面 MUST NOT 显示“补发审批”操作
|
||||
|
||||
#### Scenario: Resend approval succeeds
|
||||
|
||||
- **GIVEN** 用户对符合条件的退款申请点击“补发审批”
|
||||
- **WHEN** 接口返回 `code=0`
|
||||
- **THEN** 页面 MUST 显示成功提示并刷新列表
|
||||
- **AND** 刷新后的记录 MUST 展示接口返回的最新审批状态
|
||||
|
||||
#### Scenario: Resend approval fails
|
||||
|
||||
- **GIVEN** 接口返回非零 `code` 或请求失败
|
||||
- **WHEN** 用户触发“补发审批”
|
||||
- **THEN** 页面 MUST 展示后端返回的错误信息
|
||||
- **AND** 页面 MUST NOT 将记录标记为已补发审批
|
||||
23
openspec/changes/add-historical-approval-resend/tasks.md
Normal file
23
openspec/changes/add-historical-approval-resend/tasks.md
Normal file
@@ -0,0 +1,23 @@
|
||||
## 1. 类型与 API 契约
|
||||
|
||||
- [x] 1.1 在 `src/api/modules/agentRecharge.ts` 新增 `triggerApproval(id)` 方法
|
||||
- [x] 1.2 在 `src/api/modules/refund.ts` 新增 `triggerApproval(id)` 方法
|
||||
- [x] 1.3 确认 `AgentRecharge` 和 `Refund` 类型包含 `approval_provider`、`approval_source`、`approval_instance_id`、`approval_status`、`approval_status_name`
|
||||
|
||||
## 2. 代理充值补发审批入口
|
||||
|
||||
- [x] 2.1 在 `agentRechargeActions.ts` 增加“补发审批”动作及资格判断
|
||||
- [x] 2.2 在代理充值列表接入权限 `agent_recharge:trigger_approval` 与成功/失败处理
|
||||
- [x] 2.3 补发成功后刷新列表并展示最新审批状态
|
||||
|
||||
## 3. 退款补发审批入口
|
||||
|
||||
- [x] 3.1 在退款列表 `getActions` 增加“补发审批”动作及资格判断
|
||||
- [x] 3.2 接入权限 `refund:trigger_approval` 与成功/失败处理
|
||||
- [x] 3.3 补发成功后刷新列表并展示最新审批状态
|
||||
|
||||
## 4. 校验与验证
|
||||
|
||||
- [x] 4.1 运行 `openspec validate add-historical-approval-resend --strict`
|
||||
- [x] 4.2 运行 ESLint、类型检查并修复
|
||||
- [ ] 4.3 手工验证有/无审批实例、线上/线下充值、权限开关等场景
|
||||
@@ -0,0 +1,14 @@
|
||||
## Context
|
||||
|
||||
顶部通知抽屉已经通过通知列表接口加载最近 10 条,但当前共享状态没有保存列表分页信息。分页应复用现有通知列表接口,避免新增接口或改变通知数据契约。
|
||||
|
||||
## Decisions
|
||||
|
||||
- Decision: 分页状态由通知 store 保存,包括当前页、每页数量和总条数;列表请求返回后整体替换 `recentNotifications`。
|
||||
- Decision: 页码切换使用 `GET /api/admin/notifications?page=<page>&page_size=10`,加载期间沿用现有 loading 状态。
|
||||
- Decision: 分类切换将页码重置为 1,并重新加载列表;不使用滚动事件触发请求。
|
||||
- Decision: 分页控件放在通知列表底部,列表区域继续保持固定高度,避免抽屉整体布局跳动。
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- 分类当前由抽屉对已加载页面进行过滤,分类页的总数仍由通知列表接口返回的总体 `total` 表示;本次不扩展后端分类分页契约。
|
||||
@@ -0,0 +1,24 @@
|
||||
# Change: 通知抽屉改为分页浏览
|
||||
|
||||
## Why
|
||||
|
||||
顶部通知抽屉目前只展示最近 10 条通知,用户无法通过页码查看更早的通知。通知列表应使用明确的分页操作,避免依赖下滑加载更多的交互。
|
||||
|
||||
## What Changes
|
||||
|
||||
- 顶部通知抽屉增加页码分页控件,默认每页展示 10 条。
|
||||
- 切换页码时调用通知列表接口并替换当前列表,不追加滚动加载。
|
||||
- 切换通知分类时重置到第 1 页,并保持现有分类统计、已读和跳转行为。
|
||||
- 保留 `/api/admin/notifications` 的 `page`、`page_size` 分页参数和后端返回的 `total`。
|
||||
|
||||
## Impact
|
||||
|
||||
- Affected specs:
|
||||
- `notification-center`
|
||||
- Affected code:
|
||||
- `src/components/core/layouts/art-notification/index.vue`
|
||||
- `src/components/core/layouts/art-notification/style.scss`
|
||||
- `src/store/modules/notification.ts`
|
||||
- Out of scope:
|
||||
- 不改变通知接口、通知分类统计和已读接口。
|
||||
- 不接入下滑加载、无限滚动或新的实时推送机制。
|
||||
@@ -0,0 +1,22 @@
|
||||
## MODIFIED Requirements
|
||||
|
||||
### Requirement: Global Notification Bell
|
||||
|
||||
The admin frontend SHALL provide a global notification bell in the top navigation near the settings and user avatar entries.
|
||||
|
||||
#### Scenario: Display unread count
|
||||
|
||||
- **GIVEN** 用户已登录后台
|
||||
- **WHEN** 顶部导航加载未读通知数量
|
||||
- **THEN** 铃铛 MUST call `GET /api/admin/notifications/unread-count`
|
||||
- **AND** 数量 MUST display as `0`, `1` through `99`, or `99+`
|
||||
|
||||
#### Scenario: Open paginated notification drawer
|
||||
|
||||
- **WHEN** 用户点击顶部通知铃铛
|
||||
- **THEN** 页面 MUST display notification items from `GET /api/admin/notifications` using `page=1` and `page_size=10`
|
||||
- **AND** 抽屉 MUST provide 全部、审批、临期、同步/系统分类
|
||||
- **AND** 抽屉 MUST provide page controls based on the response `total`
|
||||
- **AND** changing page MUST replace the visible items instead of appending items from a scroll event
|
||||
- **AND** changing category MUST reset the page to 1
|
||||
- **AND** 抽屉 MUST provide an entry to `/notifications`
|
||||
@@ -0,0 +1,15 @@
|
||||
## 1. Notification State
|
||||
|
||||
- [x] 1.1 在通知 store 中保存当前页、每页数量和列表总数。
|
||||
- [x] 1.2 支持按指定页请求通知,并用新结果替换当前列表。
|
||||
|
||||
## 2. Notification Drawer
|
||||
|
||||
- [x] 2.1 在通知列表底部增加页码分页控件,默认每页 10 条。
|
||||
- [x] 2.2 切换页码时重新请求列表并回到列表顶部。
|
||||
- [x] 2.3 切换分类时重置页码并保持现有分类、已读和跳转行为。
|
||||
|
||||
## 3. Verification
|
||||
|
||||
- [x] 3.1 验证分页请求携带正确的 `page` 和 `page_size`,且列表不会累加旧页数据。
|
||||
- [x] 3.2 运行通知相关 lint、类型、格式、样式和编码检查;当前仓库暂无通知专项测试。
|
||||
Reference in New Issue
Block a user