From 6654972ddb0081ca9f02ff819a273b4b7da1372d Mon Sep 17 00:00:00 2001
From: sexygoat <1538832180@qq.com>
Date: Wed, 27 May 2026 14:58:37 +0800
Subject: [PATCH] =?UTF-8?q?feat:=20=E6=96=B0=E5=A2=9E=E9=80=80=E6=AC=BE?=
=?UTF-8?q?=E5=87=AD=E8=AF=81?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../proposal.md | 3 +-
.../specs/order-management/spec.md | 11 +-
.../update-refund-order-voucher/proposal.md | 21 ++
.../specs/order-management/spec.md | 45 +++++
.../update-refund-order-voucher/tasks.md | 9 +
.../proposal.md | 20 ++
.../specs/order-management/spec.md | 109 +++++++++++
.../tasks.md | 10 +
.../business/CreateRefundDialog.vue | 179 ++++++++++++++++--
.../business/PaymentVoucherDialog.vue | 24 ++-
src/types/api/refund.ts | 2 +
src/views/finance/refund/detail.vue | 102 ++++++++--
src/views/finance/refund/index.vue | 23 ++-
.../order-management/order-list/index.vue | 10 +-
14 files changed, 521 insertions(+), 47 deletions(-)
create mode 100644 openspec/changes/update-refund-order-voucher/proposal.md
create mode 100644 openspec/changes/update-refund-order-voucher/specs/order-management/spec.md
create mode 100644 openspec/changes/update-refund-order-voucher/tasks.md
create mode 100644 openspec/changes/update-refund-voucher-multi-image/proposal.md
create mode 100644 openspec/changes/update-refund-voucher-multi-image/specs/order-management/spec.md
create mode 100644 openspec/changes/update-refund-voucher-multi-image/tasks.md
diff --git a/openspec/changes/update-payment-voucher-drag-upload/proposal.md b/openspec/changes/update-payment-voucher-drag-upload/proposal.md
index e2250e6..a923a39 100644
--- a/openspec/changes/update-payment-voucher-drag-upload/proposal.md
+++ b/openspec/changes/update-payment-voucher-drag-upload/proposal.md
@@ -10,7 +10,8 @@
- 更新订单管理中的“创建订单”弹窗支付凭证上传区:
- 支持拖拽图片上传
- - 保留现有单文件限制、图片类型校验、5MB 大小校验、异步上传和上传中禁提交流程
+ - 保留现有单文件限制、图片类型校验、异步上传和上传中禁提交流程
+ - 不再做前端文件大小限制
- 更新资产信息中的“创建充值订单”弹窗支付凭证上传区:
- 支持拖拽图片上传
- 保留现有单文件限制、图片类型校验、5MB 大小校验、异步上传和上传中禁提交流程
diff --git a/openspec/changes/update-payment-voucher-drag-upload/specs/order-management/spec.md b/openspec/changes/update-payment-voucher-drag-upload/specs/order-management/spec.md
index 79faac7..a255604 100644
--- a/openspec/changes/update-payment-voucher-drag-upload/specs/order-management/spec.md
+++ b/openspec/changes/update-payment-voucher-drag-upload/specs/order-management/spec.md
@@ -2,7 +2,7 @@
### Requirement: Order Voucher Drag Upload
-The system SHALL support drag-and-drop image selection for payment vouchers in the admin order creation dialog.
+The system SHALL support drag-and-drop selection of any browser-recognized image format for payment vouchers in the admin order creation dialog.
#### Scenario: Drag image into order voucher upload area
@@ -17,4 +17,11 @@ The system SHALL support drag-and-drop image selection for payment vouchers in t
- **GIVEN** 用户正在后台“订单管理”中创建线下支付订单
- **WHEN** 用户点击支付凭证上传区选择一张符合要求的图片
- **THEN** 系统 MUST 继续支持原有点击选择行为
-- **AND** 系统 MUST NOT 因新增拖拽能力破坏原有单文件限制、类型校验和大小校验
+- **AND** 系统 MUST NOT 因新增拖拽能力破坏原有单文件限制和类型校验
+
+#### Scenario: Upload any image format order payment voucher without frontend size limit
+
+- **GIVEN** 用户正在后台“订单管理”中创建线下支付订单
+- **WHEN** 用户选择或拖入任意浏览器识别为图片类型的支付凭证
+- **THEN** 系统 MUST NOT reject the file based on frontend file size checks
+- **AND** 系统 MUST accept the file when its MIME type starts with `image/`
diff --git a/openspec/changes/update-refund-order-voucher/proposal.md b/openspec/changes/update-refund-order-voucher/proposal.md
new file mode 100644
index 0000000..6758767
--- /dev/null
+++ b/openspec/changes/update-refund-order-voucher/proposal.md
@@ -0,0 +1,21 @@
+# Change: Update Refund Order Voucher Requirements
+
+## Why
+
+退款管理的创建订单流程需要记录退款凭证图片,便于财务审核和后续追溯。用户也需要在退款订单列表和详情中像订单列表的支付凭证一样直接查看退款凭证。
+
+## What Changes
+
+- Add required `refund_voucher_key` to refund order creation payload, sourced from `/storage/upload-url` image upload result.
+- Add a "查看退款凭证" action in refund order list operations when the order has `refund_voucher_key`.
+- Display refund voucher directly in refund order details when `refund_voucher_key` exists.
+
+## Impact
+
+- Affected specs: `order-management`
+- Affected code:
+ - Refund management create order dialog/form and API payload typing
+ - Refund order list action column
+ - Refund order detail view
+ - Shared voucher preview/upload utilities if reused from order payment voucher flow
+- Breaking changes: Existing refund order creation now requires `refund_voucher_key`.
diff --git a/openspec/changes/update-refund-order-voucher/specs/order-management/spec.md b/openspec/changes/update-refund-order-voucher/specs/order-management/spec.md
new file mode 100644
index 0000000..2e79604
--- /dev/null
+++ b/openspec/changes/update-refund-order-voucher/specs/order-management/spec.md
@@ -0,0 +1,45 @@
+## ADDED Requirements
+
+### Requirement: Refund Order Voucher Upload
+
+The system SHALL require a refund voucher file key when creating a refund order in refund management.
+
+#### Scenario: Create refund order with uploaded voucher
+
+- **GIVEN** 用户正在退款管理中创建退款订单
+- **WHEN** 用户通过 `/storage/upload-url` 上传退款凭证图片并获得 `file_key`
+- **AND** 用户提交创建退款订单表单
+- **THEN** 系统 MUST 将该 `file_key` 作为 `refund_voucher_key` 提交
+- **AND** `refund_voucher_key` MUST be a non-empty string
+
+#### Scenario: Block refund order creation without voucher
+
+- **GIVEN** 用户正在退款管理中创建退款订单
+- **WHEN** 用户未上传退款凭证图片或未获得 `file_key`
+- **AND** 用户尝试提交创建退款订单表单
+- **THEN** 系统 MUST prevent submission
+- **AND** 系统 MUST 提示用户上传退款凭证
+
+### Requirement: Refund Voucher Viewing
+
+The system SHALL allow users to view refund vouchers from refund order list operations and refund order details when `refund_voucher_key` exists.
+
+#### Scenario: View refund voucher from refund order list action
+
+- **GIVEN** 用户正在查看退款订单列表
+- **WHEN** 某条退款订单存在 `refund_voucher_key`
+- **THEN** 系统 MUST 在操作列提供查看退款凭证入口
+- **AND** 该入口的查看体验 MUST be consistent with the existing order list payment voucher preview behavior
+
+#### Scenario: Hide refund voucher action when no voucher exists
+
+- **GIVEN** 用户正在查看退款订单列表
+- **WHEN** 某条退款订单不存在 `refund_voucher_key`
+- **THEN** 系统 MUST NOT display an enabled refund voucher preview action for that order
+
+#### Scenario: Display refund voucher in refund order detail
+
+- **GIVEN** 用户打开退款订单详情
+- **WHEN** 详情数据包含 `refund_voucher_key`
+- **THEN** 系统 MUST directly display the refund voucher image or preview entry in the detail content
+- **AND** 用户 MUST NOT need to return to the list to view the voucher
diff --git a/openspec/changes/update-refund-order-voucher/tasks.md b/openspec/changes/update-refund-order-voucher/tasks.md
new file mode 100644
index 0000000..3928bf4
--- /dev/null
+++ b/openspec/changes/update-refund-order-voucher/tasks.md
@@ -0,0 +1,9 @@
+## 1. Implementation
+
+- [x] 1.1 Update refund order creation request type to include required `refund_voucher_key: string`.
+- [x] 1.2 Add refund voucher image upload to the refund order creation form using `/storage/upload-url`, storing the returned file key.
+- [x] 1.3 Validate that refund voucher is uploaded before allowing refund order creation.
+- [x] 1.4 Submit `refund_voucher_key` in the create refund order payload.
+- [x] 1.5 Add a list operation to view the refund voucher when `refund_voucher_key` exists, matching the existing order list payment voucher behavior.
+- [x] 1.6 Show the refund voucher directly in refund order details when `refund_voucher_key` exists.
+- [x] 1.7 Verify create, list preview, and detail display flows manually or with existing tests.
diff --git a/openspec/changes/update-refund-voucher-multi-image/proposal.md b/openspec/changes/update-refund-voucher-multi-image/proposal.md
new file mode 100644
index 0000000..b6bc37f
--- /dev/null
+++ b/openspec/changes/update-refund-voucher-multi-image/proposal.md
@@ -0,0 +1,20 @@
+# Change: Update Refund Voucher Multi Image Behavior
+
+## Why
+
+退款管理需要更清晰地展示退款凭证,并支持一次退款记录关联多张凭证图片,便于财务核验。创建退款申请选择订单时也应只允许选择已支付订单,避免对未支付订单发起退款。
+
+## What Changes
+
+- 退款详情中直接展示退款凭证图片,点击图片后可放大预览。
+- 创建退款申请的订单号搜索/选择请求必须增加 `payment_status: 2` 条件。
+- 退款管理凭证上传支持多张图片,并将所有上传后的文件 key 以英文逗号拼接后放入 `refund_voucher_key` 参数。
+
+## Impact
+
+- Affected specs: `order-management`
+- Affected code:
+ - Refund detail voucher display and image preview behavior
+ - Create refund request order selector query params
+ - Refund management voucher upload component and submit payload
+- Breaking changes: Refund voucher payload field for this flow remains `refund_voucher_key` and supports one or more uploaded image keys separated by English commas.
diff --git a/openspec/changes/update-refund-voucher-multi-image/specs/order-management/spec.md b/openspec/changes/update-refund-voucher-multi-image/specs/order-management/spec.md
new file mode 100644
index 0000000..dd13d03
--- /dev/null
+++ b/openspec/changes/update-refund-voucher-multi-image/specs/order-management/spec.md
@@ -0,0 +1,109 @@
+## ADDED Requirements
+
+### Requirement: Refund Detail Inline Voucher Preview
+
+The system SHALL display refund voucher images directly in the refund detail page when voucher file keys exist, and each displayed image SHALL support click-to-enlarge preview. Refund voucher viewing from the refund list SHALL be controlled by the permission code `refund:view_voucher`.
+
+#### Scenario: Display and enlarge refund voucher in detail
+
+- **GIVEN** 用户打开退款详情页
+- **AND** 退款详情数据包含一个或多个退款凭证文件 key
+- **WHEN** 页面渲染退款凭证区域
+- **THEN** 系统 MUST 直接展示对应的凭证图片
+- **AND** 用户点击任一凭证图片后,系统 MUST 放大预览该图片
+
+#### Scenario: Hide voucher images when no voucher exists
+
+- **GIVEN** 用户打开退款详情页
+- **WHEN** 退款详情数据不包含退款凭证文件 key
+- **THEN** 系统 MUST NOT 展示空的凭证图片占位
+- **AND** 系统 MAY display `-` or equivalent empty-state text for the voucher field
+
+#### Scenario: Show refund voucher list action with permission
+
+- **GIVEN** 用户正在查看退款管理列表
+- **AND** 某条退款记录存在 `refund_voucher_key`
+- **AND** 当前用户拥有 `refund:view_voucher` 权限编码
+- **WHEN** 系统渲染该行操作列
+- **THEN** 系统 MUST show the `查看退款凭证` action
+
+#### Scenario: Hide refund voucher list action without permission
+
+- **GIVEN** 用户正在查看退款管理列表
+- **AND** 某条退款记录存在 `refund_voucher_key`
+- **AND** 当前用户不拥有 `refund:view_voucher` 权限编码
+- **WHEN** 系统渲染该行操作列
+- **THEN** 系统 MUST NOT show the `查看退款凭证` action
+
+### Requirement: Refund Application Paid Order Filtering
+
+The system SHALL restrict the order number search/select request in create refund application to paid orders by including `payment_status: 2` in the query parameters.
+
+#### Scenario: Search selectable orders for refund application
+
+- **GIVEN** 用户正在创建退款申请
+- **WHEN** 用户通过订单号搜索/选择订单
+- **THEN** 系统 MUST call the order search/list API with `payment_status: 2`
+- **AND** 未支付、已取消或其他非已支付状态订单 MUST NOT be returned as selectable refund orders by the frontend query
+
+### Requirement: Refund Application Zero Amount
+
+The system SHALL allow the requested refund amount in create refund application to be `0`, while still preventing negative amounts and amounts greater than the actual received amount.
+
+#### Scenario: Submit zero requested refund amount
+
+- **GIVEN** 用户正在创建退款申请
+- **AND** 用户已选择可退款订单
+- **WHEN** 用户输入申请退款金额 `0`
+- **THEN** 系统 MUST allow the amount validation to pass
+- **AND** 系统 MUST submit `requested_refund_amount` as `0`
+
+#### Scenario: Block negative requested refund amount
+
+- **GIVEN** 用户正在创建退款申请
+- **WHEN** 用户输入小于 `0` 的申请退款金额
+- **THEN** 系统 MUST prevent submission
+- **AND** 系统 MUST 提示申请退款金额不能小于 `0`
+
+#### Scenario: Block requested refund amount above actual received amount
+
+- **GIVEN** 用户正在创建退款申请
+- **AND** 已选订单存在实收金额
+- **WHEN** 用户输入的申请退款金额大于实收金额
+- **THEN** 系统 MUST prevent submission
+- **AND** 系统 MUST 提示申请退款金额不能大于实收金额
+
+### Requirement: Refund Management Multi Image Voucher Upload
+
+The system SHALL allow multiple refund voucher images in any browser-recognized image format to be uploaded in refund management and SHALL submit all uploaded file keys in the `refund_voucher_key` parameter as a comma-separated string.
+
+#### Scenario: Submit multiple uploaded voucher images
+
+- **GIVEN** 用户正在退款管理中创建或提交退款相关记录
+- **AND** 用户上传了多张退款凭证图片
+- **WHEN** 每张图片上传成功并返回文件 key
+- **AND** 用户提交表单
+- **THEN** 系统 MUST join the uploaded file keys with English commas
+- **AND** 系统 MUST put the joined string into `refund_voucher_key`
+- **AND** `refund_voucher_key` MUST look like `attachments/a.jpg,attachments/b.jpg` when multiple files exist
+
+#### Scenario: Upload any image format refund voucher without frontend size limit
+
+- **GIVEN** 用户正在创建退款申请
+- **WHEN** 用户选择或拖入任意浏览器识别为图片类型的退款凭证
+- **THEN** 系统 MUST NOT reject the file based on frontend file size checks
+- **AND** 系统 MUST accept the file when its MIME type starts with `image/`
+
+#### Scenario: Submit single uploaded voucher image
+
+- **GIVEN** 用户正在退款管理中创建或提交退款相关记录
+- **AND** 用户只上传了一张退款凭证图片
+- **WHEN** 用户提交表单
+- **THEN** 系统 MUST put that single file key into `refund_voucher_key` without a trailing comma
+
+#### Scenario: Block submission without required voucher image
+
+- **GIVEN** 退款管理表单要求上传退款凭证
+- **WHEN** 用户未上传任何凭证图片并尝试提交
+- **THEN** 系统 MUST prevent submission
+- **AND** 系统 MUST 提示用户上传退款凭证
diff --git a/openspec/changes/update-refund-voucher-multi-image/tasks.md b/openspec/changes/update-refund-voucher-multi-image/tasks.md
new file mode 100644
index 0000000..931e978
--- /dev/null
+++ b/openspec/changes/update-refund-voucher-multi-image/tasks.md
@@ -0,0 +1,10 @@
+## 1. Implementation
+
+- [x] 1.1 Update refund detail to render voucher images inline when voucher keys exist.
+- [x] 1.2 Add click-to-preview/enlarge behavior for refund detail voucher images.
+- [x] 1.3 Add `payment_status: 2` to the order number search/select request used by create refund application.
+- [x] 1.4 Update refund management voucher upload to allow multiple image uploads.
+- [x] 1.5 Submit uploaded voucher file keys joined by English commas in `refund_voucher_key`.
+- [x] 1.6 Validate that at least one voucher image is uploaded before submission when voucher is required.
+- [x] 1.7 Verify refund detail display, order selector filtering, and multi-image payload behavior.
+- [x] 1.8 Allow requested refund amount `0` while blocking negative and over-actual amounts.
diff --git a/src/components/business/CreateRefundDialog.vue b/src/components/business/CreateRefundDialog.vue
index e873038..73035c3 100644
--- a/src/components/business/CreateRefundDialog.vue
+++ b/src/components/business/CreateRefundDialog.vue
@@ -1,5 +1,5 @@
-
+
+
+
+
+ 将退款凭证拖到此处,或点击上传
+
+ 支持所有图片格式,可上传多张
+
+
+
@@ -59,10 +83,11 @@
+
+
diff --git a/src/components/business/PaymentVoucherDialog.vue b/src/components/business/PaymentVoucherDialog.vue
index 8b0c32b..d20c9ef 100644
--- a/src/components/business/PaymentVoucherDialog.vue
+++ b/src/components/business/PaymentVoucherDialog.vue
@@ -1,7 +1,7 @@
()
const visible = ref(false)
- const url = ref('')
+ const urls = ref([])
watch(
() => props.fileKey,
async (val) => {
if (val) {
- url.value = ''
+ urls.value = []
+ visible.value = false
+ const fileKeys = val
+ .split(',')
+ .map((key) => key.trim())
+ .filter(Boolean)
try {
const res = await StorageService.batchDownloadUrls({
- file_keys: [val]
+ file_keys: fileKeys
})
- if (res.code === 0 && res.data?.urls?.[val]) {
- url.value = res.data.urls[val]
- visible.value = true
+ if (res.code === 0) {
+ urls.value = fileKeys.map((key) => res.data.urls[key]).filter(Boolean)
+ visible.value = urls.value.length > 0
}
} catch (error) {
console.error('获取支付凭证失败:', error)
}
+ } else {
+ visible.value = false
+ urls.value = []
}
},
{ immediate: true }
@@ -49,7 +57,7 @@
const handleClose = () => {
visible.value = false
- url.value = ''
+ urls.value = []
emit('close')
}
diff --git a/src/types/api/refund.ts b/src/types/api/refund.ts
index e8e9b5d..c497027 100644
--- a/src/types/api/refund.ts
+++ b/src/types/api/refund.ts
@@ -26,6 +26,7 @@ export interface Refund {
actual_received_amount: number // 实收金额(分)
status: RefundStatus
refund_reason: string
+ refund_voucher_key?: string // 退款凭证 file_key,多个以英文逗号分隔
reject_reason: string
remark: string
asset_reset: boolean
@@ -62,6 +63,7 @@ export interface CreateRefundRequest {
order_id: number
requested_refund_amount: number // 申请退款金额(分)
actual_received_amount: number // 实收金额(分)
+ refund_voucher_key: string // 退款凭证对象存储 file_key,多个以英文逗号分隔
refund_reason?: string
}
diff --git a/src/views/finance/refund/detail.vue b/src/views/finance/refund/detail.vue
index e0a0153..d1efd9e 100644
--- a/src/views/finance/refund/detail.vue
+++ b/src/views/finance/refund/detail.vue
@@ -22,6 +22,14 @@
+
+