From 612e8562925ce73cb3858318175c4e6ca854d0f5 Mon Sep 17 00:00:00 2001
From: yeg <1347747024@qq.com>
Date: 星期三, 16 九月 2026 16:54:07 +0800
Subject: [PATCH] fix(payment): 人才端列表把「已退款」和「未支付取消」分开显示

---
 talent-card-server/src/main/java/com/talentcard/server/business/portal/UsageRecordPortalService.java        |   10 +++++++---
 talent-card-server/src/test/java/com/talentcard/server/business/payment/PendingRefundConfirmationTests.java |   17 +++++++++++++++++
 rencaika/pages/order/order.uvue                                                                             |   16 ++++++++++++++--
 3 files changed, 38 insertions(+), 5 deletions(-)

diff --git a/rencaika/pages/order/order.uvue b/rencaika/pages/order/order.uvue
index 5199bd4..69e1525 100644
--- a/rencaika/pages/order/order.uvue
+++ b/rencaika/pages/order/order.uvue
@@ -48,7 +48,7 @@
 		{ label: '待支付', value: 'pending_payment' },
 		{ label: '待核销', value: 'pending_verification' },
 		{ label: '已完成', value: 'completed' },
-		{ label: '已取消', value: 'cancelled' },
+		{ label: '已取消/已退款', value: 'cancelled' },
 		{ label: '待处理', value: 'processing' },
 		{ label: '已领取', value: 'received' }
 	]
@@ -125,6 +125,18 @@
 		const amount = Number(value)
 		return isNaN(amount) ? '' : '¥' + amount.toFixed(2)
 	}
+	/**
+	 * 已完成/待核销/待支付之外的订单都归在「已取消」这一桶里,但离开支付流程的原因不同:未支付被取消,
+	 * 还是钱已经退回来了。退款维度只改这一桶的文案,状态码与点击跳转不变。
+	 */
+	const statusLabel = (status: string, source: any): string => {
+		if (status == 'cancelled') {
+			const refundStatus = source != null && source.refundStatus != null ? Number(source.refundStatus) : 0
+			if (refundStatus == 1) return '退款中'
+			if (refundStatus == 2) return '已退款'
+		}
+		return statusText(status)
+	}
 	const mapRecord = (source: any): any => {
 		const merchantType = source != null && source.merchantType != null ? source.merchantType as string : 'service'
 		const status = source != null && source.status != null ? source.status as string : ''
@@ -140,7 +152,7 @@
 			merchantType: merchantType,
 			time: formatTime(source != null ? source.occurredAt : null),
 			statusCode: status,
-			status: statusText(status),
+			status: statusLabel(status, source),
 			amount: formatAmount(source != null ? source.amount : null),
 			icon: getMerchantIcon(merchantType),
 			iconTone: getMerchantIconTone(merchantType),
diff --git a/talent-card-server/src/main/java/com/talentcard/server/business/portal/UsageRecordPortalService.java b/talent-card-server/src/main/java/com/talentcard/server/business/portal/UsageRecordPortalService.java
index 573a112..76b74a0 100644
--- a/talent-card-server/src/main/java/com/talentcard/server/business/portal/UsageRecordPortalService.java
+++ b/talent-card-server/src/main/java/com/talentcard/server/business/portal/UsageRecordPortalService.java
@@ -92,6 +92,7 @@
 				         when o.verify_status = 1 then 'completed'
 				         else 'pending_verification'
 				       end as status,
+				       o.refund_status as refund_status,
 				       o.pay_amount as amount_cent,
 				       'ORDER_DETAIL' as target_detail_type
 				from benefit_order o
@@ -120,7 +121,8 @@
 				         else 'processing'
 				       end as status,
 				       null as amount_cent,
-				       'SERVICE_APPLICATION_DETAIL' as target_detail_type
+				       'SERVICE_APPLICATION_DETAIL' as target_detail_type,
+				       null as refund_status
 				from service_application s
 				where s.deleted = 0
 				  and exists (
@@ -139,7 +141,8 @@
 				       r.received_at as occurred_at,
 				       'received' as status,
 				       null as amount_cent,
-				       'MOVIE_TICKET_DETAIL' as target_detail_type
+				       'MOVIE_TICKET_DETAIL' as target_detail_type,
+				       null as refund_status
 				from movie_ticket_record r
 				left join cinema_coupon_claim cc on cc.claim_no = r.receive_no and cc.deleted = 0
 				where r.deleted = 0
@@ -166,7 +169,8 @@
 				       cl.created_at as occurred_at,
 				       'received' as status,
 				       null as amount_cent,
-				       'TICKET_PACKAGE_DETAIL' as target_detail_type
+				       'TICKET_PACKAGE_DETAIL' as target_detail_type,
+				       null as refund_status
 				from ticket_package_claim cl
 				join ticket_package p on p.id = cl.package_id and p.deleted = 0
 				left join merchant m on m.id = cl.merchant_id and m.deleted = 0
diff --git a/talent-card-server/src/test/java/com/talentcard/server/business/payment/PendingRefundConfirmationTests.java b/talent-card-server/src/test/java/com/talentcard/server/business/payment/PendingRefundConfirmationTests.java
index 1fa99b7..0ae6efe 100644
--- a/talent-card-server/src/test/java/com/talentcard/server/business/payment/PendingRefundConfirmationTests.java
+++ b/talent-card-server/src/test/java/com/talentcard/server/business/payment/PendingRefundConfirmationTests.java
@@ -171,6 +171,23 @@
                 .containsEntry("statusText", "已退款");
     }
 
+    @Test
+    void theTalentOrderListCarriesTheRefundStateSoARefundIsNotJustAnotherCancellation() {
+        RefundingOrder refunded = refundingOrder(2);
+
+        assertThat(((Number) recordOf(refunded.orderNo()).get("refundStatus")).intValue())
+                .as("列表要能区分「未支付被取消」和「钱已经退回来」")
+                .isEqualTo(2);
+
+        RefundingOrder refunding = refundingOrder(1);
+        when(refundGateway.queryRefund(any(), any())).thenReturn(providerResponse(Map.of(
+                "trans_stat", "P", "resp_code", "00000100", "sub_resp_desc", "交易处理中", "hf_seq_id", "HF-PENDING-" + suffix)));
+
+        Map<String, Object> refundingRecord = recordOf(refunding.orderNo());
+        assertThat(((Number) refundingRecord.get("refundStatus")).intValue()).isEqualTo(1);
+        assertThat(refundingRecord).containsEntry("status", "cancelled");
+    }
+
     /** A paid order whose refund was submitted and has no final provider answer yet. */
     private RefundingOrder refundingOrder(int refundStatus) {
         String orderNo = "REFUND-" + suffix + "-" + (++sequence);

--
Gitblit v1.7.1